payments: call CoinPay REST API directly (drop coinpay CLI dependency)

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>
This commit is contained in:
Anthony Ettinger 2026-06-14 08:27:33 +00:00
parent 5c0feda8d4
commit 7fd10c3436
6 changed files with 289 additions and 167 deletions

View file

@ -397,11 +397,14 @@ func (a *app) ensurePremium(u *store.User) bool {
if u.Premium {
return true
}
ref := payments.PremiumReference(u.PubKeyFP)
if paid, checked := payments.VerifyPremium(ref); !checked || !paid {
// Verify the CoinPay payment we created for them (if any) has settled.
if u.PremiumPayID == "" {
return false
}
if err := a.st.GrantPremium(u.ID, ref); err != nil {
if paid, checked := payments.VerifyPremium(u.PremiumPayID); !checked || !paid {
return false
}
if err := a.st.GrantPremium(u.ID, u.PremiumPayID); err != nil {
log.Error("grant premium", "err", err)
return false
}
@ -456,6 +459,10 @@ func (a *app) offerPremium(s ssh.Session, u *store.User) {
"",
}
if c, ok, err := payments.CreatePremiumCharge(ref); ok && err == nil {
// Remember the payment id so a later connect can confirm settlement.
if err := a.st.SetPremiumPayment(u.ID, c.ID); err != nil {
log.Error("store premium payment id", "err", err)
}
amount := "$" + payments.PremiumAmount() + " " + payments.PremiumCurrency()
if c.CryptoAmount != "" {
cur := c.Currency
@ -475,7 +482,7 @@ func (a *app) offerPremium(s ssh.Session, u *store.User) {
if err != nil {
log.Error("create premium charge", "err", err)
}
lines = append(lines, " pay: "+payments.PremiumPayCommand(ref))
lines = append(lines, " Payment is temporarily unavailable — please try again shortly.")
}
lines = append(lines,
"",