The starting point for the decision
Consider this design example. A team building a monthly service has verified card registration and the first payment. When next month’s payment fails, questions appear. Should access be blocked now? Can it remain available for three more days? If the customer requests cancellation in the meantime, may the payment be retried?
Connecting a recurring-payment API alone does not complete a subscription service. Beyond enrolling a payment method and collecting money, the service must connect who is charged, how much, for which period, and which features remain available until when. Separating these responsibilities is, however, a different decision from adopting a large standalone billing platform.
Toss Payments’ automatic-payment guide explains that developers must build the subscription service using its APIs and schedule approval requests according to the billing cycle. It also distinguishes issuing a billing key from using that key to collect an amount.[1] When defining development scope, examine the remaining responsibilities rather than relying on a single line labeled “recurring-payment integration.”
Separate six concepts from payment method to access rights
The following is an internal conceptual diagram for defining implementation scope. It does not represent a particular provider’s API structure or six database tables that must be created.
Customer ── enrolls ── Payment-method reference (e.g. billing key)
│ │
└─ enters ── Subscription contract │ used for payment
│ ▼
Plan / version / period → Charge → Payment attempts / transactions
│ │ success / failure / cancellation
└──────────┬─────────┘
▼
Apply grace / change / termination policies
▼
Entitlements: features / scope / expiry| Internal concept | Question to answer | Distinction from other concepts |
|---|---|---|
| Customer | Who contracts, and who pays? | The signed-in user and the company paying may differ. |
| Payment method | What can be used to pay? | Enrolling a payment method does not settle the current charge. |
| Subscription contract / plan | Which terms apply for which period? | Distinguish price, effective time, and change history from the plan name. |
| Charge | How much is due for which service period? | The amount due and its basis remain even when payment fails. |
| Payment attempt / transaction | What was actually requested, and what was the result? | A retry against the same charge differs from the next cycle’s charge. |
| Entitlement | Which features may be used now? | Reflect grace periods, free trials, and termination policies alongside payment results. |
Here, “charge” is a technical concept for managing an amount due and its applicable period. It is not inherently a tax invoice or a particular accounting treatment. The table is a design aid for finding omitted work, not a prescribed schema.
Directly replacing this internal model with provider terminology can cause confusion. Toss Payments’ customerKey, billingKey, and paymentKey respectively identify a customer, enable automatic payment, and identify a payment. Billing-key issuance returns a Billing object; successful automatic-payment approval returns a Payment object. Those keys do not themselves create an application subscription contract or entitlement.[2]
Stripe Billing, by contrast, offers objects including Customer, Product, Price, Subscription, and Invoice, connecting subscription billing with payment collection. An active Subscription does not mean every invoice has been paid.[3] Define the general structure first, then map the chosen product’s objects to their responsibilities.
From subscription terms to billing and retries — Separate plan and contract terms, then implement billing and reason-based retries across the subscription lifecycle.
Subscriptions change in more ways than success and failure
The following table separates state transitions to check when accepting subscription functionality. The last column contains policies the service must choose, not provider defaults.
| Event | Change to record separately | Policy to decide first |
|---|---|---|
| First payment succeeds | Settlement of the first charge and the initial access period | When does access open after payment confirmation? |
| Next charge becomes due | New cycle’s period, amount, and payment result | What time zone, month-end handling, and billing job apply? |
| Payment fails | This attempt’s failure reason and the unsettled amount | Are initial and renewal failures handled identically? |
| Retry | Another payment attempt against the existing charge | Which reasons permit retries, and until when? |
| Grace period | Access scope and deadline while payment remains outstanding | Are all features retained or only some? |
| Pause | Whether billing, collection, access, or a combination stops | How are resumption and charges generated during the pause handled? |
| Scheduled cancellation | Future end time and prevention of the next renewal | When does access for the already-paid period end? |
| Immediate cancellation | Contract end, access end, and remaining charges | Is a refund or final usage charge separately required? |
| Plan change | Effective time of new terms and additional or credit charges | Is it immediate or next-cycle, and is proration required? |
| Refund | Adjustment to an existing payment and its processing result | Does the subscription end, or is only a period or line item adjusted? |
In particular, do not treat subscription cancellation, payment cancellation/refund, and termination of access as one operation. Stripe distinguishes immediate from period-end subscription cancellation and handles whether and how to refund separately.[4] Deleting existing payment records or cutting access immediately merely because a customer requested cancellation prevents the service from explaining its chosen policy.
The name “pause” is also insufficient. Stripe’s pause_collection pauses collection without changing subscription status, and invoices can continue to be generated. It differs from pausing service access.[5] Instead of writing only “pause button” in a specification, state what stops and what continues.
Three decisions to make before choosing an API
How long may a customer continue using the service after payment failure?
After renewal failure, access may be restricted immediately or maintained for a grace period. A payment provider’s error code does not decide that policy.
As a design example, suppose a monthly service without a free trial chooses “no access after first-payment failure, but a 72-hour grace period after renewal failure.” It needs not only failure records but a grace-period expiry, the features allowed during it, restriction work at expiry, and access restoration after payment recovery. The 72 hours are this example’s choice, not a recommended standard or statutory period.
Retries also depend on failure reasons. Toss Payments instructs users to issue a new billing key with updated information when a card or account is reissued or expires.[1] Stripe Smart Retries likewise does not execute actual repayment for certain hard declines without a new payment method.[6] Avoid repeating approval requests at the same interval for every failure.
Should the cancellation request date equal the access end date?
With period-end cancellation, a request today must prevent the next charge while preserving the already-promised access period. Supporting immediate cancellation requires separate handling of contract termination, access revocation, and refund review.
Also distinguish not renewing the next cycle from handling an existing unpaid charge. Unless you decide whether scheduled cancellation stops all retries against prior charges or only allows already-confirmed charges to proceed, operators will behave differently. These are state-design questions, not a judgment that a particular cancellation/refund policy is legally permissible. The actual product and contract require separate review.
When should a plan change take effect?
Applying all changes from the next cycle reduces mid-period difference calculations. Opening higher-tier features immediately in the middle of a month requires decisions about the additional charge, effective time, and access treatment if the extra payment fails.
Proration and refund are not synonymous. With Stripe proration, a negative adjustment is not automatically refunded, and a positive one may not be charged immediately depending on settings. Its documentation also describes credits calculated against amounts not yet paid when plans change with outstanding invoices.[7] Before considering the calculation feature, decide which amount will actually be collected or returned, and when.
Responsibilities of the payment gateway, billing tool, application, and operator
You do not need to build the entire subscription system yourself. Even with external tools, however, record who handles what. The following allocation is proposed from boundaries documented for Toss Payments automatic-payment APIs and Stripe Billing; it is not a universal feature matrix for every payment gateway.[1][2][3][6][8]
| Owner | Work that can be assigned | Decisions and connections still owned by the service |
|---|---|---|
| Payment gateway / payment API | Enrollment, approval, lookup, cancellation, and available status notifications for contracted payment methods | Plan policy, billing time, and whether access continues after failure |
| Commercial billing tool, optional | Subscriptions, invoices, plan changes, and retries within its supported scope | Product-rule configuration, existing-system integration, and unsupported exceptions |
| Application | Customer/contract association, product features and access periods, reflection of external results | Enforcing entitlements on actual requests and recovering inconsistent state |
| Business / operations owners | Approval of pricing, grace, change, and termination policies; customer communication; exceptions | Maintaining owners, approval scope, and processing history, and validating policy changes |
Even when a commercial tool provides entitlement information, it does not finish access control inside the application. Stripe Entitlements documentation describes reading product-linked feature information through events or APIs, then granting or revoking access in the service.[8]
Assign automation execution without overlapping ownership. Decide whether your scheduler or the commercial billing tool creates charges, and which side retries failed charges. Manual operator actions should also record the underlying transaction and reason for change.
Distinguish two meanings of “retry”: webhook redelivery sends a result notification again; payment retry executes another request to collect money. Toss Payments’ webhook delivery-failure handling and Stripe’s payment-retry functionality address different responsibilities.[9][6] Receiving a webhook should not by itself trigger another collection attempt against an unpaid charge.
Eligibility to adopt a product is separate from development. Toss Payments’ official guidance requires risk review and an additional contract for automatic payments.[1] Mentioning a billing tool here does not mean it connects directly to a particular Korean gateway or is available to every business under identical conditions. Check the contracting entity, supported payment methods and currencies, and integration method.
Two services have different minimum implementation scopes
These are design examples, not actual customer cases. They compare how chosen billing rules change the required functionality, rather than comparing customer counts or revenue.
| Decision factor | A: content membership with one plan | B: business SaaS charging for seats and usage |
|---|---|---|
| Basic conditions | Monthly advance payment, one plan, no usage billing or coupons | Company contracts, multiple plans, seat/usage-based amounts, promotions |
| Change policy | Price changes apply from the next cycle. | Effective times and price-difference policies are needed for seats and plans. |
| Basis for charges | Contract version, access period, fixed amount | Contract version, seat-change history, usage aggregation period/cutoff, discount basis |
| Failure handling | Reason-specific guidance, permitted retries, grace expiry, and access restoration | Line-item review, payment-method changes, organization-specific access allowances, exception approvals |
| Minimum implementation candidate | In-app subscription/charge module, payment API, scheduler, entitlement checks, operational lookup screen | Usage collection/validation, charge calculation/preview, change history, entitlement integration, operational review |
| Tool choice | Can start without a separate billing platform if this scope can be maintained and verified. | Stronger reason to compare commercial billing with custom implementation; check unsupported rules and integration costs too. |
A does not need a complex promotion engine or usage-metering system and may be implemented as a small module in the existing application. That does not justify omitting missing-charge detection, payment-method re-enrollment, or prevention of renewal after cancellation. Infrequent refunds may be processed after operator approval, but amount, transaction, and entitlement changes must still be recorded.
In B, even defining “usage” expands the scope. Decide which events count, their cutoff, which charge receives late usage, and who approves corrections after billing closes. Commercial tools take over repeatable functions within this work; they do not eliminate business policies.
Custom implementation fits when rules are limited and the team can operate billing jobs and exceptions. External support becomes relevant when policy, implementation, verification, and operations are split across owners and responsibility falls through the gaps, rather than simply when calculations are difficult. Whichever option you choose, compare included functionality and retained work in the same table.
Connect transaction states from order to refund — Integrate payment methods with orders and verify delays, retries, cancellations and refunds.
Acceptance checks continue beyond the payment-success screen
The following acceptance scenarios supplement the design above. They are expected outcomes for testing agreed policies, not actual test results.
| Acceptance scenario | Outcome to verify |
|---|---|
| Billing-key issuance succeeds, but the first payment fails | Paid access does not open without another basis such as a free trial; the failure reason and next action are visible. |
| Payment succeeds at the gateway, but internal result application fails | A recovery path verifies the existing payment and repairs charge/entitlement state without another charge or duplicate access period. |
| Grace expires after renewal failure, or payment recovers | Restrictions and restoration follow the selected policy. Check for payment state changing while access remains unchanged. |
| Cancellation at period end is scheduled | The next renewal stops while the promised existing period remains available. Existing charges follow the agreed treatment. |
| An additional payment for a plan change fails | The result matches the decision to grant new features immediately or hold the change; billing terms and actual access must not remain on different plans. |
| A pause/resumption or refund is processed | The system explains what stopped or resumed, which payment was adjusted, and how subscription and access were affected. |
A small service may begin with limited lookup and processing screens rather than a complex operations console. Operators must still be able to verify why this customer is due to be billed and why they can use the service now. Detailed failure-reprocessing implementation and partial-refund calculations can be separate designs, but their owners and acceptance conditions must not be omitted.
Minimize the payment information you store directly
For automatic card payments, first consider a provider-hosted payment interface while the service manages payment-method references and necessary transaction identifiers. Toss Payments supports issuing billing keys through its payment window.[1] Treat billing keys and API credentials differently from ordinary customer IDs, limiting access and log exposure.
Do not store card security codes such as CVV/CVC after authorization for reuse in recurring payments. PCI SSC explains that post-authorization storage is prohibited regardless of encryption or customer consent.[10] Outsourcing payment processing does not remove all PCI DSS responsibilities; establish the scope applicable to the actual integration.[11]
Completion means being able to explain what happens next month
A small billing module can be sufficient for a simple monthly subscription. A commercial billing tool may fit better when multiple plans, seats, usage, and discounts interact. Start with the responsibilities required to keep plans, charges, payments, and access aligned in your service, rather than counting a tool’s features.
After defining the minimum scope, specify each rule’s effective time and expected outcome in the subscription billing rules and verification scenario specification. A policy-recording template and a decision about implementation scope serve different purposes.
If you are deciding which plan, billing, entitlement, or failure-handling responsibilities to outsource, review the scope of IXC recurring payment and billing services.


