> ## Documentation Index
> Fetch the complete documentation index at: https://doc.haipay.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Subscription (Legacy navigation V20260628)

> Historical subscription guide comparing Checkout Mode (payUrl redirect) with the Front-End Component that shows Google Pay, Apple Pay, and cards in one container, plus launch requirements and dispute fees.

HaiPay subscription payment supports membership, recurring services, auto-renewal, and other periodic billing scenarios. This page covers integration modes, key business rules, and launch requirements. For detailed API fields and debugging, refer to the corresponding API Reference.

> **[Quick Start](#quick-start)**
>
> Review integration steps, prerequisites, and recommended reading path.

> **[Integration Modes](#integration-modes)**
>
> Compare Checkout Mode and Front-End Component.

> **[Core APIs](#core-apis)**
>
> Jump to subscription apply, query, cancel, and refund endpoints.

> [!WARNING]
>
> * Provide clear subscription entry, billing cycle description, and unsubscribe entry.
> * Notify users via email or other off-site channels before and after each charge.
> * Provide a confirmable subscription agreement and only initiate after explicit user authorization.
> * Maintain customer support availability, at least covering service hours in primary operating regions.

> [!TIP]
>
> * Consumers may initiate a dispute within 180 days after a credit card charge.
> * Each dispute incurs a \$20 dispute handling fee.
> * If you choose to contest, an additional \$20 representment fee applies.
> * If the representment is successful, HaiPay refunds the representment fee; the original dispute handling fee is non-refundable.

> [!CAUTION]
>
> PCI DSS strictly prohibits embedding credit card input pages in `WebView` or `iframe`. Always complete card information collection and payment authorization in a trusted browser environment to avoid compliance risks and sensitive data exposure.

## Quick Start

**1. Confirm Business Model and Prerequisites**

First read the [API Description Guide](https://doc.haipay.net/en/history/V20260628/get-started/api-conventions.md) and [Subscription Flow](https://doc.haipay.net/en/history/V20260628/payments/subscriptions/workflow.md) to confirm your scenario is recurring billing, not one-time payment.

**2. Choose Integration Mode**

Subscription payment offers two integration modes: **PayUrl Redirect Mode** (server obtains authorization link, redirects to HaiPay hosted page) and **Front-End Component Mode** (embed payment components in your own page using a client token). Choose based on your checkout design and frontend capabilities.

**3. Integrate APIs, Notifications, and Cancellation**

After completing the subscription apply, you need to query subscription status, handle charge callbacks, and provide a cancellation entry for users. Detailed fields and debugging entry points are in the API Reference cards below.

## Integration Modes

Subscription payment offers two integration modes. The core difference is who hosts the payment page:

| Comparison | Checkout Mode | Front-End Component |
| :- | :- | :- |
| Payment Page | Redirect to HaiPay hosted page | Embed payment components in merchant page |
| Frontend Work | Minimal, just handle redirects | Requires JS script and event listeners |
| UI Control | Low, styled by HaiPay | High, fully customizable |
| Key Return Field | `payUrl` from response | `clientToken` from response |
| Best For | Quick integration, no custom UI needs | Custom checkout, immersive payment |

**Checkout Mode**

The simplest integration method. After the merchant server calls the subscription apply API, use the returned `payUrl` to redirect the user to the HaiPay hosted page for authorization and first payment.

**Integration Flow**

**1. Server calls subscription apply API**

The merchant server sends a [subscription apply](https://doc.haipay.net/en/history/V20260628/api-reference/subscription/api/subscriptionApply.md) request to HaiPay, including subscription amount, cycle, Callback URL, and other required parameters.

**2. Get payUrl and redirect**

The response includes a `payUrl` field. Redirect the user's browser to this URL.

**3. User completes payment**

The user completes credit card entry and payment authorization on the HaiPay hosted page. After payment, HaiPay redirects the user back to the merchant's `callBackUrl` and sends an async notification to `notifyUrl`.

**Example code (frontend redirect after server obtains payUrl)**

```javascript theme={null}
// Assume your server has called the subscription apply API and returned payUrl
const payUrl = response.data.payUrl;

// Redirect in current window
window.location.href = payUrl;

// Or open in new window
// window.open(payUrl, '_blank');
```

**Recommendations**

* Fastest subscription integration with minimal frontend changes.
* No strong custom UI requirements for the payment page.
* Redirect experience usually works well for mobile H5 scenarios.

**Front-End Component Mode**

By including the HaiPay Front-End Component script, embed payment components in the merchant's own page. After calling the subscription apply API, use the returned `clientToken` to initialize the frontend component, allowing users to pay without leaving your page.

Best for modern subscription checkout that displays `Google Pay`, `Apple Pay`, and `Credit Card` in a single container.

**Recommended Script**

`https://cashier.haipay.top/js/paymentMethodsSubscribe_1.0.0.min.js`

**Key Parameters**

| Parameter | Required | Description |
| :- | :- | :- |
| `sandbox` | Yes | `true` for test, `false` for production |
| `clientToken` | Yes | Client token |
| `themeMode` | No | Theme mode, default `light` |
| `paymentMethodConfig` | No | Payment method combination, default `["GOOGLE_PAY","APPLE_PAY","CREDIT_CARD"]` |
| `applePayButtonType` | No | Apple Pay button text, e.g. `buy`, `subscribe` |
| `googlePayButtonType` | No | Google Pay button text, e.g. `buy`, `subscribe` |

**Key Events**

* `ready`: Buttons rendered
* `error`: Initialization or payment error
* `paymentStatus`: Payment result callback (if not listened, the component handles the result by default)

**Recommendations**

* Recommended for new checkout pages — clearer information architecture.
* If only some payment methods are needed, pass only the required combination.
* Reduces frontend customization effort.
* When using Front-End Component, pass `paymentMethods` instead of `inBankCode` in the Subscription Apply API, e.g. `CREDIT_CARD,GOOGLE_PAY,APPLE_PAY`.

```javascript theme={null}
<script src="https://cashier.haipay.top/js/paymentMethodsSubscribe_1.0.0.min.js"></script>

<div>
  <div id="paymentId"></div>
</div>

const elements = paymentMethodsSubscribe.create({
  sandbox: true,
  clientToken: 'your-client-token',
  themeMode: 'light',
  paymentMethodConfig: ['GOOGLE_PAY', 'APPLE_PAY', 'CREDIT_CARD']
});

elements.mount('#paymentId');

elements.on('ready', (data) => {
  console.log('rendered successfully:', data);
});

elements.on('error', (data) => {
  console.error('Payment error:', data);
});

elements.on('paymentStatus', (data) => {
  console.log('payment status:', data);
});
```

## Core APIs

For detailed request fields, response structures, and online debugging, go directly to the API Reference:

> **[Subscription Apply](https://doc.haipay.net/en/history/V20260628/api-reference/subscription/api/subscriptionApply.md)**
>
> Create a subscription order, initiate user authorization, and complete the first payment.

> **[Subscription Query](https://doc.haipay.net/en/history/V20260628/api-reference/subscription/subscription-query.md)**
>
> Query subscription status, platform subscription number, and charge records.

> **[Subscription Cancel](https://doc.haipay.net/en/history/V20260628/api-reference/subscription/subscription-cancel.md)**
>
> Merchant-initiated cancellation to stop future recurring charges.

## Async Notifications

When subscription status changes or a recurring charge completes, HaiPay pushes async notifications to the `notifyUrl` provided during subscription apply.

> [!TIP]
>
> To ensure API extensibility and compatibility, follow these callback parameter receiving practices:
>
> 1. **Do NOT** declare specific POJO objects to receive callback parameters.
> 2. **MUST** use generic data structures (e.g. JSONObject, Map) for parameter parsing.
> 3. This design ensures that future callback field extensions will not affect signature verification.

After receiving a notification, return **SUCCESS** (uppercase) in the response body.

**Subscription Status Notification**

Triggered when subscription status changes (e.g. success, cancel, failure).

| Parameter | Type | Description |
| :- | :- | :- |
| `type` | String | Notification type, fixed as `SUBSCRIPTION` |
| `appId` | Long | Business ID |
| `currency` | String | Currency |
| `subscriptionOrderId` | String | Merchant subscription order ID |
| `subscriptionNo` | String | Platform subscription number |
| `amount` | String | Subscription amount |
| `status` | Integer | Subscription status (1: processing, 2: success, 3: failed, 4: cancelled, 5: completed) |
| `recurringInterval` | String | Recurring interval type (D/W/M/Y) |
| `recurringIntervalCount` | Integer | Recurring interval count |
| `subject` | String | Subscription title |
| `sign` | String | Signature (use the business key corresponding to the currency for verification) |

**Subscription Charge Notification**

Triggered when a recurring charge succeeds or fails.

| Parameter | Type | Description |
| :- | :- | :- |
| `type` | String | Notification type, fixed as `SUBSCRIPTIONS_DEDUCT` |
| `appId` | Long | Business ID |
| `currency` | String | Currency |
| `subscriptionOrderId` | String | Merchant subscription order ID |
| `subscriptionNo` | String | Platform subscription number |
| `deductNo` | String | Charge number |
| `orderNo` | String | Platform order number |
| `amount` | String | Charge amount |
| `status` | Integer | Charge status (2: success, 3: failed) |
| `startTime` | String | Current charge cycle start time, format: yyyy-MM-dd HH:mm:ss |
| `endTime` | String | Current charge cycle end time, format: yyyy-MM-dd HH:mm:ss |
| `sign` | String | Signature (use the business key corresponding to the currency for verification) |

## Key Business Rules

| Item | Description |
| :- | :- |
| Transaction Limit | Subscription amount range: `0.99 - 1000 USD` |
| Max Duration | Maximum subscription duration is 3 years regardless of interval unit |
| Interval Unit | Apple Pay does not support `W`; use `D` + `7` days for weekly |
| Payment Type | Fixed as `SUBSCRIPTION` for subscription scenarios |
| User Notification | Recommended to send off-site notifications after subscription success, before and after charges |
| Unsubscribe | Production must provide a clear, accessible cancellation entry |
| Payment Method Parameter | Pass either `inBankCode` or `paymentMethods` in the Subscription Apply API: `inBankCode` for a single payment method, `paymentMethods` for a comma-separated list. `paymentMethods` currently only supports the Front-End Component Mode |

> [!TIP]
>
> For test card numbers, see [Test Card Numbers](https://doc.haipay.net/en/history/V20260628/testing/test-cards.md)

## Frequently Asked Questions

> **When should I use this page vs. the API Reference?**
>
> This page helps you understand product capabilities, choose integration modes, and learn business rules. For development and debugging, go directly to the [Subscription API Reference](https://doc.haipay.net/en/history/V20260628/api-reference/subscription/api/subscriptionApply.md) for complete fields, sample payloads, and debugging tools.

> **Why must subscription businesses emphasize unsubscribe entry and off-site notifications?**
>
> Subscription transactions are more prone to user disputes. Clear authorization, notification, and cancellation capabilities significantly reduce chargebacks, complaints, and risk control issues — key prerequisites for stable subscription operations.

> **How to handle Unsupported region: CN in production?**
>
> This usually means the production environment does not support the region, or the test configuration does not match the target region. Verify merchant configuration, target market, and payment method combination, then contact HaiPay support to confirm production availability.

> **How to choose between Checkout Mode and Front-End Component?**
>
> For fastest launch with minimal frontend changes, choose Checkout Mode. For custom checkout UI where users stay on your page, choose Front-End Component Mode. Both modes use the same Subscription Apply API — the only difference is whether you use the returned `payUrl` or `clientToken`.

> **Should I pass inBankCode or paymentMethods?**
>
> Choose one — they cannot be passed together or both empty. For a single payment method, pass `inBankCode`. For multiple payment methods (e.g. Front-End Component Mode), pass `paymentMethods`. Note: `paymentMethods` currently only supports the Front-End Component Mode; other modes should continue using `inBankCode`.

> **What mode is recommended for a quick modern subscription page?**
>
> If using Front-End Component Mode, it displays multiple payment methods in a single container for a more complete page, lower user cognitive load, and more manageable frontend development.

## Related Topics

* [Apple Pay Subscription](https://doc.haipay.net/en/history/V20260628/api/version2/ApplePay.md)
* [Google Pay Subscription](https://doc.haipay.net/en/history/V20260628/api/version2/GooglePay.md)
* [Merchant Initiated Transaction (MIT)](https://doc.haipay.net/en/history/V20260628/payments/cards/merchant-initiated-transactions.md)
* [VISA/MASTER Payment](https://doc.haipay.net/en/history/V20260628/api/version2/creditcard.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.