Plans are in early access and subject to change. To request Plans access, contact hi@natural.com.
POST /plans, a subscription sets terms.amount, the amount of every payment (at least $0.50), and terms.every, its one interval. Its terms.paymentCount reads null.
Installments
An installment plan splits one purchase into 2 to 4 payments. InPOST /plans, set the purchase’s total in terms.totalAmount, the number of payments in terms.paymentCount, and the time between payments in terms.every, on the same intervals as a subscription.
terms.payments.
Payment 1 is charged in checkout, on the day the payer agrees, and payment n falls n-1 intervals after that day. A payer who agrees on Jan 31 to monthly payments pays on Jan 31, Feb 28 and Mar 31. Checkout shows the payer every date before they agree, and the dates don’t change after that. nextPayment.dueDate gives the next one.
Tax
amount and totalAmount are what the payer pays, tax included. To say how much of it is tax, set terms.taxAmount, which defaults to 0. Every payment of a subscription carries taxAmount. An installment plan’s tax is split the same way as its total, with the cents that don’t divide evenly on payment 1, and terms.payments lists each payment’s taxAmount. Each payment’s payment intent carries its share. The agreement the payer accepts names each payment’s tax, and each payment’s receipt shows its tax.
Lifecycle
- Create a plan with
POST /plans. It startspendingand returns acheckoutUrland aclientSecret. To stop checkout taking payment after a deadline, setexpiresAt. A pending plan can’t be changed, and neither can its checkout’s payment intent. To offer other terms, end the plan (see Canceling) and create a new one. - The payer agrees to the terms and pays payment 1 in checkout. The plan becomes
active, andmandateIdnames the card agreement it charges. - Natural charges each later payment automatically when it falls due. A payment can be charged from 12:00 UTC on its due date until 30 days later, or until the next payment opens if that’s sooner. To charge one yourself inside that window, use
POST /plans/{planId}/payments, which returns the card payment.GET /card-payments?planId={planId}lists every card payment whoseplanis that plan, newest first: each attempt at each payment, payment 1’s checkout attempts included. - A plan becomes
canceledwhen the payer or you cancel it, when the payer’s bank stops its agreement, when checkout ends or expires without payment 1, or when the agreement can’t be set up. An installment plan becomesfinishedonce every payment is paid or skipped. A canceled plan stays canceled, even if a charge already under way then pays its last payment.
GET /plans lists your plans, newest first. Pass status to list only the plans in one status, such as needs_attention.
Embed checkout
To take payment 1 on your own page instead of sending the payer tocheckoutUrl, pass the plan’s clientSecret from your server to the payer’s browser. It’s set whenever checkoutUrl is, so it’s null once checkout ends. Treat it like a password. Mount Natural’s payment form with it:
TypeScript
Missed payments
A declined payment is retried inside its window. If it still isn’t paid, it’s missed:missedPayments lists it and the plan is past_due. Natural never charges a missed payment late, so collect it another way. Later payments are still charged on schedule.
A plan becomes needs_attention, and Natural stops collecting, when two payments in a row are missed or when the bank declines the card in a way that rules out a retry. attention.reason says which.
Once you’ve collected a missed payment another way, mark it with POST /plans/{planId}/skip, so it’s no longer owed. That includes a payment whose window closed while the plan was stopped. Skipping a payment first records any earlier payments that already lapsed as missed, so they stay owed until you skip them too. Skip only settles a missed payment: it doesn’t skip an upcoming one, and it doesn’t restart a plan that needs attention. To start collecting again, call POST /plans/{planId}/resume.
Canceling
You can cancel a plan withPOST /plans/{planId}/cancel. A subscription’s payer can also cancel it online, on its manage page. An installment plan’s payer can view it there but can’t cancel it, because they still owe its remaining payments. When a plan is canceled, Natural revokes its card agreement and sends mandate.revoked, with revocationReason payer_canceled or merchant_canceled. Natural charges nothing more and emails the payer a confirmation. A charge already under way when the plan is canceled can still go through, and the plan’s payments stay listed.
Canceling a plan that’s still pending cancels its checkout instead, so the payer can’t pay payment 1, and the plan becomes canceled. There’s no agreement yet, so you get paymentIntent.canceled rather than mandate.revoked, and the payer isn’t emailed. If the payer has already submitted payment 1, the cancel is refused with plan_pending until its outcome lands. Once it’s paid and the plan is active, a cancel revokes the agreement as above.
The payer reaches the manage page from Natural’s emails. The plan’s confirmation, each receipt and each failed-payment email link to it: “Manage or cancel” for a subscription, “View your plan” for an installment plan. Hosted checkout’s confirmation links to it too, for a subscription. The link asks for a code sent to the email the payer confirmed in checkout.
The manage page shows the plan’s terms and status, its next payment, its payments and the card on file, and lets a subscription’s payer cancel.
Plan payments and webhooks
Every charge of a plan is a card payment with plan fields only plans carry:planhas the plan’sid, itskind, and thepaymentNumberthe charge pays. Payment 1 is the checkout payment.- A later payment has
channelapi, because Natural charged the card without the payer present, andmandateIdnames the card agreement it was charged on.
GET /card-payments?planId={planId} and GET /card-payments/{cardPaymentId}. Every charge, payment 1 included, sends cardPayment.created, then cardPayment.succeeded or cardPayment.failed, each with the same fields. A successful charge also sends paymentIntent.completed.