The live CoinPay API returns crypto_amount as a bare JSON number (e.g.
0.0031), but the struct decoded it as a string, so /payments/create failed
with "cannot unmarshal number into ... crypto_amount of type string" and
join@ showed "Payment is temporarily unavailable". The unit test had hidden
the bug by sending the value quoted.
Add a flexStr type that unmarshals from either a JSON number or string and
use it for crypto_amount; update the test to send a number and add a direct
flexStr decode test for both forms.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CreatePremiumCharge/VerifyPremium now POST /payments/create and GET
/payments/:id against the CoinPay API (Bearer COINPAY_API_KEY, business_id =
AGENTBBS_COINPAY_MERCHANT_ID), so the droplet needs no coinpay CLI installed.
The created payment id is stored (store: User.PremiumPayID + premium_pay_id col
+ SetPremiumPayment); ensurePremium verifies that id on a later connect and
grants premium on confirmed/forwarded status. Removed the CLI command-template
env knobs; added AGENTBBS_COINPAY_API_URL. Tests: httptest-backed payments_test
+ store SetPremiumPayment test. Build/vet/gofmt/test green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>