Guides / Payments
Subscriptions
Charge your customers every week, month or year with a saved card. You keep the plan, the price and the schedule in your own system. Weav saves the card and charges it whenever you ask, with no customer present.
Saving cards is off until Weav turns it on for your account. Weav asks for your PCI DSS evidence first. In test mode it always works, so you can build your integration now.
1. Save the card at sign-up
Charge the first period and save the card in one step. Add save_payment_method and customer.id (your own ID for the customer) to a CARD payment:
POST /v1/payments
{ "channel": "CARD", "currency": "PHP", "amount": 499.00, "external_reference_id": "SUB-USER-123-2026-11", "save_payment_method": true, "customer": { "id": "USER-123", "name": "Juan dela Cruz" }, "success_url": "https://shop.example.com/account/plan" }A checkout works too: send "channels": ["CARD"] so your customer can only pay by card. Your customer agrees to future charges on Weav’s page and confirms the payment with their bank.
Then you get PAYMENT_COMPLETED and PAYMENT_METHOD_SAVED. Keep the saved card’s id (PM…) with the subscription. To save a card without charging it, see Saved cards.
2. Charge on your schedule
Run your own job, for example once a day. For each subscription that’s due, charge its card:
POST /v1/payments
{ "payment_method_id": "PM8K2Q7X9KBAT4MZ3N", "currency": "PHP", "amount": 499.00, "external_reference_id": "SUB-USER-123-2026-12", "description": "December plan" }- Use one
external_reference_idper period. If your job crashes and sends the same request again, Weav returns the same payment instead of charging twice (see Idempotency). COMPLETED: paid. Extend the subscription.PENDINGwithnext_action.checkout_url: your customer’s bank wants them to confirm this charge. Send them the link by email or in your app.FAILED: see step 3.
The same result comes as a webhook (PAYMENT_COMPLETED or PAYMENT_FAILED), so your job doesn’t have to wait for it.
flowchart LR
C[Charge the<br/>saved card] --> S{Status}
S -->|COMPLETED| OK[Extend the<br/>subscription]
S -->|PENDING| L[Send your customer<br/>checkout_url]
L -. paid .-> OK
S -->|FAILED| T{Tried a<br/>few times?}
T -->|No| R[Try again a day later,<br/>with a new reference]
R --> C
T -->|Yes| N[Ask for<br/>another card]3. When a charge fails
- Try again later. A new try is a new payment, so give it a new reference, such as
SUB-USER-123-2026-12-2. The same reference returns the same failed payment. Leave at least a day between tries, and stop after a few. - Ask for another card. Send your customer a payment with
save_payment_method(step 1) for the amount due. It charges the new card and saves it. Then remove the old one.
4. Before a card expires
Saved cards carry their expiry (card.exp_month, card.exp_year). Once a month, list the cards that expire soon and ask those customers for a new card before a charge fails:
GET /v1/payment-methods?expires_by=2026-125. Keep track
GET /v1/payments?payment_method_id=PM8K2Q7X9KBAT4MZ3N: every charge on a saved card, such as a subscription’s history.GET /v1/payment-methods?customer_id=USER-123: a customer’s saved cards.
6. When your customer cancels
Stop charging their card in your system. If they ask you to remove the card, DELETE /v1/payment-methods/{id} removes it at the card processor too, so nobody can charge it again.
Good to know
- Charge only what you told your customer. They agreed to future charges when they saved the card. Tell them the amount and when you’ll charge it, and tell them how to cancel.
- Weav doesn’t run the schedule. There are no plans or invoices in Weav: you decide what to charge and when.
- Test mode: save Visa •••• 0002 to try a declined charge, and Mastercard •••• 4444 to try an expiring card. See Test mode.