# Next Commerce: Payments and gateways > Gateways, payment methods, gateway selection on API-created orders, disputes, and the Test Gateway. NEXT Payments processing rates are not published. This is one of 6 domain bundles derived from the platform capability map at https://developers.nextcommerce.com/capabilities.json (generated 2026-09-03). The other bundles are listed at https://developers.nextcommerce.com/llms.txt. Merchant and operator guides are on https://docs.nextcommerce.com; the changelog is https://docs.nextcommerce.com/changelog. The Admin API contract is the OpenAPI file at https://developers.nextcommerce.com/api/admin/2024-04-01.yaml. ## Capabilities ### Payments and gateways (id: payments-gateways) Merchants add bankcard gateways and alternative payment methods under Settings > Payments and group them for routing and failure cascading. Developers choose a gateway on an API-created order with payment_details.payment_gateway or payment_gateway_group, and integrate each payment method through its guide. NEXT Payments is the platform's own processing service. Status: available. Audiences: merchant, developer. Links verified: 2026-09-03. Caveats: - NEXT Payments processing rates are not published in the documentation; they are quoted by sales. Merchant and operator guides (docs.nextcommerce.com): - https://docs.nextcommerce.com/docs/features/payments - https://docs.nextcommerce.com/docs/start-here/get-started/add-payment-providers - https://docs.nextcommerce.com/docs/features/payments/gateways/next-payments - https://docs.nextcommerce.com/docs/features/payments/payment-failure-cascading - https://docs.nextcommerce.com/docs/features/payments/authorize-and-capture-payments - https://docs.nextcommerce.com/docs/features/payments/3ds2-payments - https://docs.nextcommerce.com/docs/features/payments/external-payment-methods - https://docs.nextcommerce.com/docs/features/payments/risk-screening - https://docs.nextcommerce.com/docs/features/payments/transaction-response-codes Developer guides (developers.nextcommerce.com): - https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods - https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/bankcard - https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/apple-pay - https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/google-pay - https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/paypal - https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/klarna - https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/affirm - https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/afterpay - https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/link - https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/bancontact - https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/ideal - https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/sepa-debit - https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/swish - https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/twint Admin API operations, version 2024-04-01 (18): - [GET /disputes/ — Retrieve a list of disputes.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/disputesList) - [POST /disputes/ — Create a new dispute.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/disputesCreate) - [GET /disputes/{id}/ — Retrieve a dispute.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/disputesRetrieve) - [PUT /disputes/{id}/ — Update an existing dispute.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/disputesUpdate) - [PATCH /disputes/{id}/ — Partial update an existing dispute.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/disputesPartialUpdate) - [DELETE /disputes/{id}/ — Delete an existing dispute.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/disputesDestroy) - [GET /disputes/{id}/notes/ — Retrieve a list of all dispute notes in an existing dispute.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/disputesNotesList) - [POST /disputes/{id}/notes/ — Create an dispute note in an existing dispute.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/disputesNotesCreate) - [POST /disputes/{id}/resolve/ — Resolve a dispute with a resolution and optional external refund.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/disputesResolveCreate) - [GET /gateway-groups/ — Retrieve a list of gatway groups.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/gatewayGroupsList) - [GET /gateway-groups/{id}/ — Retrieve a gatway group.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/gatewayGroupsRetrieve) - [GET /gateways/ — Retrieve a list of gateways.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/gatewaysList) - [GET /gateways/{id}/ — Retrieve a gateway.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/gatewaysRetrieve) - [GET /transactions/ — Retrieve a list of transactions.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/transactionsList) - [POST /transactions/verify/ — Verify a card token.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/transactionsVerifyCreate) - [GET /transactions/{id}/ — Retrieve a transaction.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/transactionsRetrieve) - [POST /transactions/{id}/capture/ — Capture an existing transaction.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/transactionsCaptureCreate) - [POST /transactions/{id}/refund/ — Refund an existing transaction.](https://developers.nextcommerce.com/docs/admin-api/reference/payments/transactionsRefundCreate) Webhook events (4): - [gateway.created](https://developers.nextcommerce.com/docs/webhooks/reference/payments/gateway.created) - [gateway.updated](https://developers.nextcommerce.com/docs/webhooks/reference/payments/gateway.updated) - [transaction.created](https://developers.nextcommerce.com/docs/webhooks/reference/payments/transaction.created) - [transaction.updated](https://developers.nextcommerce.com/docs/webhooks/reference/payments/transaction.updated) ### Disputes (id: disputes) Disputes are chargebacks. Merchants review and respond to them in the dashboard and report on them; apps can act as a dispute service and receive dispute events. Status: available. Audiences: merchant, developer. Links verified: 2026-09-03. Merchant and operator guides (docs.nextcommerce.com): - https://docs.nextcommerce.com/docs/features/payments/disputes-guide - https://docs.nextcommerce.com/docs/analytics/disputes-reports Developer guides (developers.nextcommerce.com): - https://developers.nextcommerce.com/docs/apps/guides/dispute-service Webhook events (2): - [dispute.created](https://developers.nextcommerce.com/docs/webhooks/reference/payments/dispute.created) - [dispute.updated](https://developers.nextcommerce.com/docs/webhooks/reference/payments/dispute.updated) ### Testing and test orders (id: testing) There is no separate sandbox. Test cards (6011111111111117, and 6011000990139424 for 3DS) create tagged Test Orders on live stores without touching a gateway; the Test Gateway produces realistic test transactions when an integration needs them. Status: available. Audiences: merchant, developer. Links verified: 2026-09-03. Caveats: - Do not tell a prospect there is no test mode; test cards work on live stores. Merchant and operator guides (docs.nextcommerce.com): - https://docs.nextcommerce.com/docs/manage/orders/test-orders - https://docs.nextcommerce.com/docs/features/payments/gateways/test-gateway Developer guides (developers.nextcommerce.com): - https://developers.nextcommerce.com/docs/testing - https://developers.nextcommerce.com/docs/admin-api/guides/testing-guide ## Pages The full text of every developer page cited above, in the order listed. # Payment Methods (https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods) Guides for creating [Admin API](https://developers.nextcommerce.com/docs/admin-api/guides/external-checkout) orders with each supported payment method. The matrix below summarizes each method's flow type and capabilities — see the individual guide for request details and payment-specific data. ## Capability matrix [#capability-matrix] | Payment Method | Flow | Express | Upsells | Subscriptions | | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- | ------- | ------- | ------------- | | [`card_token`](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/bankcard) | Direct & Redirect ([3DS](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/bankcard#3d-secure-3ds2)) | Yes | Yes | Yes | | [`apple_pay`](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/apple-pay) | Redirect | Yes | Yes | Yes | | [`google_pay`](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/google-pay) | Redirect | Yes | Yes | Yes | | [`paypal`](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/paypal) | Redirect | Yes | Yes | Yes | | [`klarna`](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/klarna) | Redirect | No | Yes | Yes | | [`link`](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/link) | Redirect | Yes | Yes | Yes | | [`twint`](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/twint) | Redirect | No | Yes | Yes | | [`swish`](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/swish) | Redirect | No | No | No | | [`affirm`](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/affirm) | Redirect | No | No | No | | [`afterpay`](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/afterpay) | Redirect | No | No | No | | [`bancontact`](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/bancontact) | Redirect | No | No | No | | [`ideal`](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/ideal) | Redirect | No | No | No | | [`sepa_direct`](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/sepa-debit) | Redirect | No | No | No | > **Note:** **Upsells** (post-purchase, one-click) are added via [`ordersAddLineItemsCreate`](https://developers.nextcommerce.com/docs/admin-api/reference/orders/ordersAddLineItemsCreate), which reuses the order's initial payment method to collect payment. This requires the payment method to support merchant-initiated charges — see each guide's **Upsells** section. ## Redirect payment flow [#redirect-payment-flow] Every method except direct card tokenization completes payment through a redirect flow: # Bankcard (https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/bankcard) Bankcard is the core payment method on the Admin API. Cards are charged by passing `payment_method: card_token` with a tokenized card in `payment_details`. Tokenizing the card with our iFrame payment form keeps sensitive card data off your servers and reduces your PCI compliance scope. This guide covers the full bankcard flow: * **[Gateway routing](#gateway-routing)** — route charges across one or more payment gateways * **[Card tokenization](#card-tokenization-iframe)** — get a `card_token` with the iFrame payment form * **[3D Secure (3DS2)](#3d-secure-3ds2)** — process cards through an authentication flow ## Order payment payload [#order-payment-payload] Bankcard orders set `payment_method` to `card_token` and pass the tokenized card (and any optional fields) in `payment_details`: ```json title="Bankcard Payment Detail" "payment_method": "card_token", "payment_details": { "card_token": "", // from the iFrame (see below) "save_card": true, // retain card for future charges (default true) "statement_descriptor": "BRANDNAME", // optional, up to 22 chars "payment_gateway": 12, // optional, route to a specific gateway "payment_gateway_group": 3, // optional, route to a gateway group "payment_return_url": "" // required for 3DS (see below) } ``` | Field | Type | Description | | ----------------------- | ------------ | ---------------------------------------------------------------------------------------------------------- | | `card_token` | string | Tokenized card produced by the iFrame payment form. | | `save_card` | boolean | Retain the card for future charges (subscriptions, one-click upsells). Defaults to `true`. | | `statement_descriptor` | string | Custom bank-statement descriptor (≤ 22 alphanumeric chars, spaces, and `& , . - #`). | | `payment_gateway` | integer | Optional — charge a **specific gateway** by id. See [Gateway routing](#gateway-routing). | | `payment_gateway_group` | integer | Optional — charge a **gateway group** by id. See [Gateway routing](#gateway-routing). | | `payment_return_url` | string (uri) | Required for **3DS** — your endpoint that receives the final order data. See [3D Secure](#3d-secure-3ds2). | > **Note:** For the complete order request (lines, user, addresses, shipping), see the [External Checkout Flow](https://developers.nextcommerce.com/docs/admin-api/guides/external-checkout) guide. This guide focuses on the bankcard-specific payment detail. ## Gateway Routing [#gateway-routing] By default, bankcard charges route through your store's configured payment gateway. For stores with **more than one gateway**, you can optionally pin a charge to a specific gateway or gateway group by passing one of these fields in `payment_details`: | Field | Type | Routes to | | ----------------------- | ------- | ------------------------------------------------------------------------ | | `payment_gateway` | integer | A **single gateway** by its `id`. | | `payment_gateway_group` | integer | A **gateway group** by its `id` — the platform selects a member gateway. | ```json title="Route to a specific gateway or group" "payment_method": "card_token", "payment_details": { "card_token": "", "payment_gateway": 12 // OR "payment_gateway_group": 3 } ``` > **Note:** Pass **either** `payment_gateway` **or** `payment_gateway_group` — not both. If neither is provided, the store's default routing is used. ### Get gateway and group ids [#get-gateway-and-group-ids] The ids are integers from the Payments API: * **Gateways** — [`gatewaysList`](https://developers.nextcommerce.com/docs/admin-api/reference/payments/gatewaysList) / [`gatewaysRetrieve`](https://developers.nextcommerce.com/docs/admin-api/reference/payments/gatewaysRetrieve) * **Gateway groups** — [`gatewayGroupsList`](https://developers.nextcommerce.com/docs/admin-api/reference/payments/gatewayGroupsList) / [`gatewayGroupsRetrieve`](https://developers.nextcommerce.com/docs/admin-api/reference/payments/gatewayGroupsRetrieve) A gateway group also exposes its supported `available_currencies`, `available_payment_methods`, and `card_types`, so you can pick the right group for a given order. ### When to route [#when-to-route] Most stores let the platform route automatically. Pass an explicit gateway or group when you need to: * **Load balance** — distribute volume across multiple gateways/processors. * **Region or currency routing** — send orders to the gateway that supports a given currency or market. * **Failover** — direct traffic to a backup gateway, or use a group so a soft-declined charge can be re-attempted on another gateway in the group. > **Note:** Group membership, distribution weighting, and soft-decline re-attempt behavior are configured per gateway in your store dashboard — the API selects among what's already configured. ## Card Tokenization (iFrame) [#card-tokenization-iframe] Custom off-site checkouts can reduce their PCI compliance scope by leveraging our iFrame payment form to tokenize credit cards before submitting them on the Admin API. > **Note:** View a fully functional [Demo](https://nextcommerceco.github.io/demo-iframe-payment-form/) to see all of the concepts in action. The demo source code is also available on [Github](https://github.com/NextCommerceCo/demo-iframe-payment-form/blob/main/index.html). The iframe payment form is a pure JS library that provides managed fields for the card number and security code to safely collect sensitive credit card information. The fields can be styled to match your external checkout HTML pages for a seamless end-user experience. > **Note:** We have partnered with [Spreedly](https://docs.spreedly.com/reference/iframe/v1/#setfieldtype) for all bankcard payments; this guide leverages their iFrame payment documentation and how to use the iFrame JS with our platform. ### Setup [#setup] Before you get started, grab your Payments Environment Key from your store dashboard (**Settings > Payments**) — we'll use this to map the iFrame to your store's payment environment. **Card tokenization steps** 1. Add a payment form with card fields (name, card number, expiration, and cvv). 2. Add Spreedly JS and initialize the iFrame on managed fields. 3. Style the iFrame form fields to match your design. 4. Tokenize the card with a form submit handler. 5. Retrieve the card token. ```html title="Example Payment Form HTML"




``` After you have the form on your page, initialize the iFrame fields on card number and cvv. ```html title="Add JS and Configure" ``` > **Note:** Note how the `numberEl` and `cvvEl` map to div element ids in the form to render the managed fields. ### Style iFrame Fields [#style-iframe-fields] For the best end-user experience, customize the iFrame form fields so they blend in with your native form fields. ```js title="Example form customization" // example styles for iframe fields, accepts any style that can be applied with JS var style = 'color: #212529; font-size: 1rem; line-height: 1.5; font-weight: 400; \ width: calc(100% - 20px); height: calc(100% - 2px); position: absolute;'; // set placeholders and styles for iframe fields to make UI style Spreedly.on("ready", function () { Spreedly.setFieldType('text'); Spreedly.setPlaceholder('cvv', "CVV"); Spreedly.setPlaceholder('number', "Card Number"); Spreedly.setNumberFormat('prettyFormat'); Spreedly.setStyle('cvv', style); Spreedly.setStyle('number', style); submitBtn.removeAttribute('disabled'); }); ``` ### Tokenize Card [#tokenize-card] Tokenize the card with your form submission handler. The `tokenizeCreditCard` method requires that the `requiredFields` are passed as an object for form validation. ```js title="Tokenize Card on Form Submit" function submitPaymentForm() { var requiredFields = {}; // Get required, non-sensitive, values from host page form requiredFields["full_name"] = document.getElementById("full_name").value; requiredFields["month"] = document.getElementById("month").value; requiredFields["year"] = document.getElementById("year").value; // tokenize the card Spreedly.tokenizeCreditCard(requiredFields); } ``` ### Retrieve Card Token [#retrieve-card-token] When a card has been tokenized, the `paymentMethod` event is fired that includes the generated payment method token as well as the details of the payment method record. **Use the token from your custom checkout backend to send to the Admin API when creating the order.** ```js title="Retrieve Card Token" Spreedly.on('paymentMethod', function (token, pmData) { // create your own handler to capture the token and send to your backend console.log(token); console.log(pmData); }); ``` ### Error Handling [#error-handling] When a card fails validation, the `errors` event is fired which includes an array of objects with `attribute`, `key`, and `message` fields describing the errors for each field. ```js title="Error Handling" Spreedly.on('errors', function(errors) { // add your own error handler to show errors to users so they can fix them for (var i=0; i < errors.length; i++) { var error = errors[i]; console.log(error); }; }); ``` ```json title="Example Errors" [ { "attribute":"first_name", "key":"errors.blank", "message":"First name can't be blank" }, { "attribute":"last_name", "key":"errors.blank", "message":"Last name can't be blank" } ] ``` ### Customizing the iFrame Fields [#customizing-the-iframe-fields] The iFrame fields can be customized to match your site styles. See the [demo](https://github.com/NextCommerceCo/demo-iframe-payment-form/blob/main/index.html) for a full example. #### setFieldType [#setfieldtype] Set the input type of the iFrame fields. This is useful when you want different keyboards to display on mobile devices. By default, the iFrame fields are set to `type=number`, which displays the numerical keyboard in most browsers on most mobile devices. However, behavior does vary by browser. If you'd like to manually control the input field type you can do so with `setFieldType`. **Arguments** | Name | Description | | ----- | --------------------------------------------------------------------- | | field | The iFrame field to set the placeholder. Can be one of number or cvv. | | type | The input field type. Can be one of number, text or tel. | ```js title="setFieldType" Spreedly.on('ready', function() { Spreedly.setFieldType("number", "tel"); }); ``` #### setNumberFormat [#setnumberformat] Set the card number format. If set to `prettyFormat`, the card number value will include spaces in the credit card number as they appear on a physical card. **The number field must be set to type text or tel for pretty formatting to take effect.** **Arguments** | Format | User Input | Display | | --------------------- | ------------------ | --------------------- | | prettyFormat | `4111111111111111` | `4111 1111 1111 1111` | | plainFormat (default) | `4111111111111111` | `4111111111111111` | | maskedFormat | `4111111111111111` | `****************` | ```js title="setNumberFormat" // Pretty format Spreedly.on('ready', function() { Spreedly.setFieldType("number", "text"); Spreedly.setNumberFormat("prettyFormat"); }); // Masked format Spreedly.on('ready', function() { Spreedly.setFieldType("cvv", "text"); Spreedly.setFieldType("number", "text"); Spreedly.setNumberFormat("maskedFormat"); }); ``` #### setPlaceholder [#setplaceholder] Style iFrame fields' placeholder text if page design requires so. **Arguments** | Name | Description | | ----------- | --------------------------------------------------------------------- | | field | The iFrame field to set the placeholder. Can be one of number or cvv. | | placeholder | The placeholder text value. | ```js title="setPlaceholder" Spreedly.on('ready', function() { Spreedly.setPlaceholder("number", "Card"); Spreedly.setPlaceholder("cvv", "CVV"); }); ``` #### setStyle [#setstyle] Style iFrame fields using CSS. More than one invocation of setStyle can be used per field to organize and better structure styling directives. **Arguments** | Name | Description | | ----- | --------------------------------------------------------------------------------------------------------------------------------------------- | | field | The iFrame field to set the placeholder. Can be one of number or cvv. | | css | The CSS to apply. Should be vanilla CSS, -moz-appearance, or -webkit-appearance. All CSS properties should be constructed as a single string. | ```js title="setStyle" Spreedly.on("ready", function() { Spreedly.setStyle("number", "width:225px; height:35px;"); Spreedly.setStyle("number", "font-size: 20px; text-align: center"); Spreedly.setStyle("cvv", "width:60px; height:35px;"); }); ``` > **Warning:** Importing external fonts or images is not supported due to CORS restrictions. #### transferFocus [#transferfocus] Set the cursor focus to one of the iFrame fields. This is useful if you want to load your form with the card number field already in focus, or auto-focus a field that contains an input error. ```js title="transferFocus" Spreedly.transferFocus("number"); ``` **Arguments** | Name | Description | | ----- | --------------------------------------------------------------------- | | field | The iFrame field to set the placeholder. Can be one of number or cvv. | #### toggleAutoComplete [#toggleautocomplete] Toggle autocomplete functionality for card number and cvv fields. **By default, the autocomplete attribute is enabled**, so the first call of this function will disable autocomplete. ```js title="toggleAutoComplete" Spreedly.toggleAutoComplete(); ``` ## 3D Secure (3DS2) [#3d-secure-3ds2] 3DS2 payments are fully supported via the Admin API to process the customer through an authentication flow, with the final transaction information and results provided back to your application. > **Note:** Your store must have a 3DS2-enabled gateway to process 3DS2 transactions. ### API payment redirect flow [#api-payment-redirect-flow] ### Create the order [#create-the-order] When creating an order using a 3DS2-enabled gateway, use `payment_method=card_token` and provide a `payment_return_url`. The `payment_return_url` is your endpoint that will receive a POST request containing the final order data. ```json title="Payment Details for Order with 3DS2 Payment" "payment_method": "card_token", "payment_details": { "card_token": "", "payment_return_url": "", "payment_gateway": 12, // optional "payment_gateway_group": 3 // optional } ``` > **Tip:** You can optionally provide a `payment_gateway` or `payment_gateway_group` (see [Gateway routing](#gateway-routing)) to authenticate against a specific gateway configured in the store. ### Redirect to the payment complete URL [#redirect-to-the-payment-complete-url] The order response provides a `payment_complete_url`. Redirect the customer to this URL to complete the payment authentication. ```json title="Response with Payment Complete URL" { "reference_transaction_id": null, "payment_complete_url": "https:///payments/3ds-auth/?token=" } ``` ### Receive order data [#receive-order-data] # Apple Pay Admin API Guide (https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/apple-pay) **Apple Pay** is a fully integrated payment app, supported both in the storefront checkout, and via the Admin API. Apple Pay transactions process the customer through the Apple Pay payment flow, with the resulting order information provided back to your application. Below are the steps needed to get Apple Pay set up and working on the Admin API. For custom checkouts using the Admin API, there are two flows available -- the standard method where a user enters their shipping address, chooses products, and then checks out via Apple Pay; and the "One-Click" method, where the user is not required to enter shipping information before being redirected to Apple Pay checkout. > **Note:** Your store must have a Apple Pay setup and enabled with a gateway to use the Apple Pay payment method. The user device must also be an Apple Device with Touch ID enabled. See more on [displaying Apple Pay buttons](https://developer.apple.com/documentation/apple_pay_on_the_web/displaying_apple_pay_buttons_using_css) or the [Apple Pay Demo](https://applepaydemo.apple.com/). ### API Payment Redirect Flow [#api-payment-redirect-flow] ### Create Order on Admin API [#create-order-on-admin-api] When creating a new order using Apple Pay, you’ll need to specify the `payment_method=apple_pay` as well as provide a `payment_return_url`. The `payment_return_url` is your endpoint that will receive a POST request containing the final order data. ```json title="Payment Details for Order with Apple Pay" { "payment_method": "apple_pay", "payment_details": { "payment_return_url": "", "payment_gateway": "", // optional "payment_gateway_group": "" // optional } } ``` ### Redirect Customer to Payment Complete URL [#redirect-customer-to-payment-complete-url] The response when creating the order will provide a payment\_complete\_url. Your application should redirect the customer to this URL for completing the payment on the store's Apple Pay Checkout page. ```json title="Response with Payment Complete URL" { "reference_transaction_id": null, "payment_complete_url": "https:///checkout/apple-pay//" } ``` ### Receiving Order Data [#receiving-order-data] # Google Pay Admin API Guide (https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/google-pay) **Google Pay** is a fully integrated payment app, supported both in the storefront checkout, and via the Admin API. Google Pay transactions process the customer through the Google Pay payment flow, with the resulting order information provided back to your application. Below are the steps needed to get Google Pay set up and working on the Admin API. For custom checkouts using the Admin API, there are two flows available -- the standard method where a user enters their shipping address, chooses products, and then checks out via Google Pay; and the "One-Click" method, where the user is not required to enter shipping information before being redirected to Google Pay checkout. > **Note:** Your store must have a Google Pay setup and enabled with a gateway to use the Google Pay payment method and the user device must use Chrome browser or Android with Google Pay setup. ### API Payment Redirect Flow [#api-payment-redirect-flow] ### Create Order on Admin API [#create-order-on-admin-api] When creating a new order using Google Pay, you’ll need to specify the `payment_method=google_pay` as well as provide a `payment_return_url`. The `payment_return_url` is your endpoint that will receive a POST request containing the final order data. ```json title="Payment Details for Order with Google Pay" { "payment_method": "google_pay", "payment_details": { "payment_return_url": "", "payment_gateway": "", // optional "payment_gateway_group": "" // optional } } ``` > **Tip:** To test Google Pay as a payment method, you can use the `test` gateway with your real credit card in your Google Pay account, your card will not be charged. ### Redirect Customer to Payment Complete URL [#redirect-customer-to-payment-complete-url] The response when creating the order will provide a payment\_complete\_url. Your application should redirect the customer to this URL for completing the payment on the store's Google Pay Checkout page. ```json title="Response with Payment Complete URL" { "reference_transaction_id": null, "payment_complete_url": "https:///checkout/google-pay//" } ``` ### Receiving Order Data [#receiving-order-data] # PayPal Admin API Guide (https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/paypal) **PayPal** is a fully integrated payment app that is supported both in the storefront checkout, and via the Admin API. PayPal transactions send the customer through a PayPal redirect flow, with the resulting order information provided back to your application. Below are the steps needed to get PayPal set up and working on the Admin API. For custom PayPal checkouts, there are two checkout flows available, the standard method where a user enters their shipping address, chooses products, and then checks out via PayPal; and the "One-Click" method, where the user is not required to enter shipping information before being redirected to PayPal checkout. ### API Payment Redirect Flow [#api-payment-redirect-flow] ### Create Order on Admin API [#create-order-on-admin-api] When creating a new order using PayPal using the orders\_create API method, you must specify the `payment_method=paypal` as well as provide a `payment_return_url`. The `payment_return_url` is your endpoint that will receive a POST request containing the final order data. ```json title="Payment Details for Order with PayPal" { "payment_method": "paypal", "payment_details": { "payment_return_url": "", "paypal_account": "" // optional } } ``` > **Tip:** You can optionally provide a `paypal_account` when creating the order to use a PayPal account other than the store default PayPal account. ### Redirect Customer to Paypal [#redirect-customer-to-paypal] The response when creating the order will provide a `payment_complete_url`. Your application should redirect the customer to this URL for completing the payment on PayPal. ```json title="Response with Payment Complete URL" { "reference_transaction_id": null, "payment_complete_url": "https://www.paypal.com/checkoutnow?token=" } ``` ### Receiving Order Data [#receiving-order-data] ### Upsells [#upsells] Paypal supports one-click upsells through the [ordersAddLineItemsCreate](https://developers.nextcommerce.com/docs/admin-api/reference/orders/ordersAddLineItemsCreate) API, enabling additional items to be added to the order with a payment transaction. > **Note:** To process upsells, the Paypal account must have [Reference Transactions](https://developer.paypal.com/api/nvp-soap/do-reference-transaction-soap/) enabled and configured on the store. If the store Paypal account has reference transactions enabled, the [ordersCreate](https://developers.nextcommerce.com/docs/admin-api/reference/orders/ordersCreate) API response will include `supports_post_purchase_upsells: true`, signaling you can process one-click upsell transactions. # Klarna Admin API Guide (https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/klarna) **Klarna** is a fully integrated payment method via NEXT Payments and Stripe, supported both in the storefront checkout and via the Admin API. Klarna transactions send the customer through a Klarna redirect flow, with the resulting order information provided back to your application. Below are the steps needed to get Klarna set up and working on the Admin API. ### API Payment Redirect Flow [#api-payment-redirect-flow] ### Create Order on Admin API [#create-order-on-admin-api] When creating a new order using Klarna using the orders\_create API method, you must specify the `payment_method=klarna` as well as provide a `payment_return_url`. The `payment_return_url` is your endpoint that will receive a POST request containing the final order data. ```json title="Payment Details for Order with Klarna" { "payment_method": "klarna", "payment_details": { "payment_return_url": "", "payment_gateway": "", // optional "payment_gateway_group": "" // optional } } ``` > **Tip:** You can optionally provide a `payment_gateway` when creating the order to use a Klarna account connected to a specific gateway. ### Redirect Customer to Klarna [#redirect-customer-to-klarna] The response when creating the order will provide a `payment_complete_url`. Your application should redirect the customer to this URL for completing the payment on Klarna. ```json title="Response with Payment Complete URL" { "reference_transaction_id": null, "payment_complete_url": "" } ``` ### Receiving Order Data [#receiving-order-data] ### Upsells [#upsells] Klarna supports one-click upsells through the [ordersAddLineItemsCreate](https://developers.nextcommerce.com/docs/admin-api/reference/orders/ordersAddLineItemsCreate) API, enabling additional items to be added to the order with a payment transaction. ### Recurring [#recurring] Klarna via NEXT Payments supports recurring transactions and can be used as a payment method for an order with subscription items. # Affirm Admin API Guide (https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/affirm) **Affirm** is a fully integrated Buy Now Pay Later (BNPL) payment method via NEXT Payments and Stripe, supported both in the storefront checkout, and via the Admin API. Affirm transactions send the customer through an Affirm redirect flow, with the resulting order information provided back to your application. Below are the steps needed to get Affirm set up and working on the Admin API. ### API Payment Redirect Flow [#api-payment-redirect-flow] ### Create Order on Admin API [#create-order-on-admin-api] When creating a new order using Affirm using the orders\_create API method, you must specify the `payment_method=affirm` as well as provide a `payment_return_url`. The `payment_return_url` is your endpoint that will receive a POST request containing the final order data. ```json title="Payment Details for Order with Affirm" { "payment_method": "affirm", "payment_details": { "payment_return_url": "", "payment_gateway": "", // optional "payment_gateway_group": "" // optional } } ``` > **Tip:** You can optionally provide a `payment_gateway` when creating the order to use an Affirm account connected to a specific gateway. ### Redirect Customer to Affirm [#redirect-customer-to-affirm] The response when creating the order will provide a `payment_complete_url`. Your application should redirect the customer to this URL for completing the payment on Affirm. ```json title="Response with Payment Complete URL" { "reference_transaction_id": null, "payment_complete_url": "" } ``` ### Receiving Order Data [#receiving-order-data] ### Upsells [#upsells] Upsells are not supported with Affirm payments. # Afterpay Admin API Guide (https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/afterpay) **Afterpay** is a fully integrated Buy Now Pay Later (BNPL) payment method via Stripe, supported in the storefront checkout and through the Admin API. Afterpay transactions send the customer through an Afterpay redirect flow, with the resulting order information returned to your application. Before using Afterpay, activate it on the Stripe account connected to the gateway. In the United Kingdom the same method is branded **Clearpay**. ### API Payment Redirect Flow [#api-payment-redirect-flow] ### Create Order on Admin API [#create-order-on-admin-api] When creating an order with the `orders_create` API method, specify `payment_method=afterpay` and provide a `payment_return_url`. The `payment_return_url` is your endpoint that receives a POST request containing the final order data. ```json title="Payment Details for Order with Afterpay" { "payment_method": "afterpay", "payment_details": { "payment_return_url": "", "payment_gateway": "", // optional "payment_gateway_group": "" // optional } } ``` > **Tip:** You can optionally provide a `payment_gateway` when creating the order to use an Afterpay account connected to a specific gateway. ### Redirect Customer to Afterpay [#redirect-customer-to-afterpay] The order response provides a `payment_complete_url`. Redirect the customer to this URL to complete the payment with Afterpay. ```json title="Response with Payment Complete URL" { "reference_transaction_id": null, "payment_complete_url": "" } ``` ### Receiving Order Data [#receiving-order-data] ### Upsells [#upsells] One-click post-purchase upsells are not supported with Afterpay payments. Afterpay authorizes a single sale and the payment method cannot be reused for a later merchant-initiated charge. ### Recurring [#recurring] Afterpay cannot be used as the payment method for an order with subscription items. # Link Admin API Guide (https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/link) **Link** is a fully integrated express payment method via Stripe, supported both in the storefront checkout and via the Admin API. Link transactions send the customer through a Link redirect flow, with the resulting order information provided back to your application. Below are the steps needed to get Link set up and working on the Admin API. ### API Payment Redirect Flow [#api-payment-redirect-flow] ### Create Order on Admin API [#create-order-on-admin-api] When creating a new order using Link using the orders\_create API method, you must specify the `payment_method=link` as well as provide a `payment_return_url`. The `payment_return_url` is your endpoint that will receive a POST request containing the final order data. ```json title="Payment Details for Order with Link" { "payment_method": "link", "payment_details": { "payment_return_url": "", "payment_gateway": "", // optional "payment_gateway_group": "" // optional } } ``` > **Tip:** You can optionally provide a `payment_gateway` when creating the order to use a Link account connected to a specific gateway. ### Redirect Customer to Link [#redirect-customer-to-link] The response when creating the order will provide a `payment_complete_url`. Your application should redirect the customer to this URL for completing the payment on Link. ```json title="Response with Payment Complete URL" { "reference_transaction_id": null, "payment_complete_url": "" } ``` ### Receiving Order Data [#receiving-order-data] ### Upsells [#upsells] Link supports one-click upsells through the [ordersAddLineItemsCreate](https://developers.nextcommerce.com/docs/admin-api/reference/orders/ordersAddLineItemsCreate) API, enabling additional items to be added to the order with a payment transaction. ### Recurring [#recurring] Link via Stripe supports recurring transactions and can be used as a payment method for an order with subscription items. # Bancontact Admin API Guide (https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/bancontact) **Bancontact** is a fully integrated payment method that is supported both in the storefront checkout, and via the Admin API. Bancontact transactions send the customer through a Bancontact redirect flow, with the resulting order information provided back to your application. Below are the steps needed to get Bancontact set up and working on the Admin API. ### API Payment Redirect Flow [#api-payment-redirect-flow] ### Create Order on Admin API [#create-order-on-admin-api] When creating a new order using Bancontact using the orders\_create API method, you must specify the `payment_method=bancontact` as well as provide a `payment_return_url`. The `payment_return_url` is your endpoint that will receive a POST request containing the final order data. ```json title="Payment Details for Order with Bancontact" { "payment_method": "bancontact", "payment_details": { "payment_return_url": "", "payment_gateway": "", // optional "payment_gateway_group": "" // optional } } ``` > **Tip:** You can optionally provide a `payment_gateway` when creating the order to use a Bancontact account connected to a specific gateway. ### Redirect Customer to Bancontact [#redirect-customer-to-bancontact] The response when creating the order will provide a `payment_complete_url`. Your application should redirect the customer to this URL for completing the payment on Bancontact. ```json title="Response with Payment Complete URL" { "reference_transaction_id": null, "payment_complete_url": "" } ``` ### Receiving Order Data [#receiving-order-data] ### Upsells [#upsells] Upsells are not supported with Bancontact payments. # iDEAL Admin API Guide (https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/ideal) **iDEAL** is a fully integrated payment method that is supported both in the storefront checkout, and via the Admin API. iDEAL transactions send the customer through a iDEAL redirect flow, with the resulting order information provided back to your application. Below are the steps needed to get iDEAL set up and working on the Admin API. ### API Payment Redirect Flow [#api-payment-redirect-flow] ### Create Order on Admin API [#create-order-on-admin-api] When creating a new order using iDEAL using the orders\_create API method, you must specify the `payment_method=ideal` as well as provide a `payment_return_url`. The `payment_return_url` is your endpoint that will receive a POST request containing the final order data. ```json title="Payment Details for Order with iDEAL" { "payment_method": "ideal", "payment_details": { "payment_return_url": "", "payment_gateway": "" // optional } } ``` > **Tip:** You can optionally provide a `payment_gateway` when creating the order to use a iDEAL account connected to a specific gateway. ### Redirect Customer to iDEAL [#redirect-customer-to-ideal] The response when creating the order will provide a `payment_complete_url`. Your application should redirect the customer to this URL for completing the payment on iDEAL. ```json title="Response with Payment Complete URL" { "reference_transaction_id": null, "payment_complete_url": "" } ``` ### Receiving Order Data [#receiving-order-data] ### Upsells [#upsells] Upsells are not supported with iDEAL payments. # SEPA Direct Debit Admin API Guide (https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/sepa-debit) **SEPA Direct Debit** is a fully integrated payment method that is supported both in the storefront checkout, and via the Admin API. SEPA Direct Debit transactions send the customer through a SEPA Direct Debit redirect flow, with the resulting order information provided back to your application. Below are the steps needed to get SEPA Direct Debit set up and working on the Admin API. ### API Payment Redirect Flow [#api-payment-redirect-flow] ### Create Order on Admin API [#create-order-on-admin-api] When creating a new order using SEPA Direct Debit using the orders\_create API method, you must specify the `payment_method=sepa_debit` as well as provide a `payment_return_url`. The `payment_return_url` is your endpoint that will receive a POST request containing the final order data. ```json title="Payment Details for Order with SEPA Direct Debit" { "payment_method": "sepa_debit", "payment_details": { "payment_return_url": "", "payment_gateway": "", // optional "payment_gateway_group": "" // optional } } ``` > **Tip:** You can optionally provide a `payment_gateway` when creating the order to use a SEPA Direct Debit account connected to a specific gateway. ### Redirect Customer to SEPA Direct Debit [#redirect-customer-to-sepa-direct-debit] The response when creating the order will provide a `payment_complete_url`. Your application should redirect the customer to this URL for completing the payment on SEPA Direct Debit. ```json title="Response with Payment Complete URL" { "reference_transaction_id": null, "payment_complete_url": "" } ``` ### Receiving Order Data [#receiving-order-data] ### Upsells [#upsells] Upsells are not supported with SEPA Direct Debit payments. # Swish Admin API Guide (https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/swish) **Swish** is a fully integrated payment method through NEXT Payments, supported in the storefront checkout and through the Admin API. Swish transactions send the customer through a hosted payment flow, with the resulting order information returned to your application. Before using Swish, make sure it is enabled for the NEXT Payments account and store. Swish is available for eligible Swedish checkout traffic in SEK. ### API Payment Redirect Flow [#api-payment-redirect-flow] ### Create Order on Admin API [#create-order-on-admin-api] When creating an order with the `orders_create` API method, specify `payment_method=swish` and provide a `payment_return_url`. The `payment_return_url` is your endpoint that receives a POST request containing the final order data. ```json title="Payment Details for Order with Swish" { "payment_method": "swish", "payment_details": { "payment_return_url": "", "payment_gateway": "", // optional "payment_gateway_group": "" // optional } } ``` > **Tip:** You can optionally provide a `payment_gateway` or `payment_gateway_group` to route the order through a specific eligible NEXT Payments configuration. ### Redirect Customer to Swish [#redirect-customer-to-swish] The order response provides a `payment_complete_url`. Redirect the customer to this URL to complete the payment with Swish. ```json title="Response with Payment Complete URL" { "reference_transaction_id": null, "payment_complete_url": "" } ``` ### Receiving Order Data [#receiving-order-data] ### Upsells [#upsells] One-click post-purchase upsells are not supported with Swish payments. ### Recurring [#recurring] Swish cannot be used as the payment method for subscription items. # Twint Admin API Guide (https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/twint) **Twint** is a fully integrated payment method via NEXT Payments supported both in the storefront checkout, and via the Admin API. Twint transactions send the customer through a Twint redirect flow, with the resulting order information provided back to your application. Below are the steps needed to get Twint set up and working on the Admin API. ### API Payment Redirect Flow [#api-payment-redirect-flow] ### Create Order on Admin API [#create-order-on-admin-api] When creating a new order using Twint using the orders\_create API method, you must specify the `payment_method=twint` as well as provide a `payment_return_url`. The `payment_return_url` is your endpoint that will receive a POST request containing the final order data. ```json title="Payment Details for Order with Twint" { "payment_method": "twint", "payment_details": { "payment_return_url": "", "payment_gateway": "", // optional "payment_gateway_group": "" // optional } } ``` > **Tip:** You can optionally provide a `payment_gateway` when creating the order to use a Twint account connected to a specific gateway. ### Redirect Customer to Twint [#redirect-customer-to-twint] The response when creating the order will provide a `payment_complete_url`. Your application should redirect the customer to this URL for completing the payment on Twint. ```json title="Response with Payment Complete URL" { "reference_transaction_id": null, "payment_complete_url": "" } ``` ### Receiving Order Data [#receiving-order-data] ### Upsells [#upsells] Twint supports one-click upsells through the [ordersAddLineItemsCreate](https://developers.nextcommerce.com/docs/admin-api/reference/orders/ordersAddLineItemsCreate) API, enabling additional items to be added to the order with a payment transaction. ### Recurring [#recurring] Twint via NEXT Payments supports recurring transactions and can be used as a payment method for an order with subscription items. # Dispute Service Apps (https://developers.nextcommerce.com/docs/apps/guides/dispute-service) Dispute service apps are integrations that manage the processing of payment disputes (alerts and chargebacks) on behalf of merchants seamlessly within the platform. > **Note:** Dispute Service Apps are [Server to Server Apps](https://developers.nextcommerce.com/docs/apps/guides/server-to-server-apps) that use the Oauth flow to obtain API Access and then use the [Admin APIs](https://developers.nextcommerce.com/docs/admin-api) and [Webhooks](https://developers.nextcommerce.com/docs/webhooks) to subscribe to store event activity. ## Disputes [#disputes] Disputes are complaints initiated by the customer against the merchant pertaining to their orders and are categorized into two broad groups by type, Alerts and Chargebacks, see below. * **Alerts** - disputes that are not yet a chargeback, ie TC40, SAFE, and RDR alerts. * **Chargeback** - disputes that are registered as a chargeback with the acquiring bank. ## Dispute Flow Overview [#dispute-flow-overview] Below is a high-level overview of a typical flow for a dispute service app to handle transaction disputes. ```mermaid sequenceDiagram autonumber Customer->>Store: New Transaction Created Store->>Dispute Service: transaction.created webhook event Processor->>Dispute Service: Receives transaction dispute Dispute Service->>Store: Creates dispute (alert or chargeback) in store Dispute Service->>Store: Matches dispute to store transaction Store-->>Customer: Customer is added to block lists Dispute Service-->>Store: Create refund (optional) Dispute Service-->>Store: Cancel fulfillment (recommended) Dispute Service->>Store: Resolve dispute ``` ## Dispute Flow Detail [#dispute-flow-detail] ### Step 1 - New Transaction Created [#step-1---new-transaction-created] There are several scenarios that create new payment transactions: * Order created - nearly all new orders start with a new payment transaction. * Upsell created - adding an upsell creates a new payment transaction. * Refund created - refunding a order creates a refund transaction. Orders typically have many associated transactions for the payments and refunds. ### Step 2 - `transaction.created` webhook event [#step-2---transactioncreated-webhook-event] Dispute service apps should subscribe to the `transaction.created` webhook event to be notified of all payment transaction events on a store so that your app is aware of new payments, refunds, and can handle disputes properly. > **Note (Use `parent_id` to associate related transactions):** Transaction `parent_id` will show the related transaction in the following cases: > > * `refund` transactions - the parent is the debit transaction. > * `capture` transactions - the parent is the authorization transaction. > * `void` transactions - the parent is the authorization transaction. Your app can also subscribe to `order.created` and `order.updated` events to receive more detailed order information such as items purchased, fulfillment tracking numbers, and items that have already been refunded. Create your webhook after the app is installed using the [webhooksCreate](https://developers.nextcommerce.com/docs/admin-api/reference/webhooks/webhooksCreate) Admin API and pass the `transaction.created, order.created, order.updated` to subscribe to these events. ### Step 3 - Dispute service receives transaction dispute [#step-3---dispute-service-receives-transaction-dispute] At this stage, the dispute service is responsible for receiving disputes from their integration partners. ### Step 4 - Dispute service creates dispute (alert or chargeback) in store [#step-4---dispute-service-creates-dispute-alert-or-chargeback-in-store] When disputes are identified as belonging to a store, the dispute service should create a new dispute using the [disputesCreate](https://developers.nextcommerce.com/docs/admin-api/reference/payments/disputesCreate) Admin API. ### Step 5 - Dispute service matches dispute to transaction [#step-5---dispute-service-matches-dispute-to-transaction] Disputes created in the store need to be matched to the transaction in the store to associate it with the order/customer. Disputes can be matched by passing the `transaction` parameter when creating or with update using the [disputesUpdate](https://developers.nextcommerce.com/docs/admin-api/reference/payments/disputesUpdate) Admin API. See example below in [Match a Dispute](#matching-disputes). > **Note (Tokenized payment methods may require auth_code matching):** Apple Pay, Google Pay, and other tokenized payment methods use virtualized card numbers that alert services like Ethoca may not match. See [Matching Tokenized Payments](#matching-tokenized-payments) for fallback strategies using `auth_code`. ### Step 6 - Customer is added to block lists [#step-6---customer-is-added-to-block-lists] Merchants can configure their store to automatically add customers to block lists when any of their transactions have been disputed to mitigate future risk from the customer and associated payment methods. See [Block Lists](https://docs.nextcommerce.com/docs/features/payments/block-lists) guide in our user docs. ### Step 7 - Dispute service creates refund [#step-7---dispute-service-creates-refund] Depending on the type of dispute, the dispute service may need to create a refund using the [transactionsRefundCreate](https://developers.nextcommerce.com/docs/admin-api/reference/payments/transactionsRefundCreate) Admin API to resolve the dispute. See [Create a Refund](#creating-refunds) detail below. > **Note (RDR Alerts — use external refunds):** For RDR alerts, the refund is already processed by the gateway. Your app should log it as an external refund with `is_external: true` to keep the store's transaction record accurate. See [RDR Alerts](#rdr-alerts) below. ### Step 8 - Cancel Order / Cancel Fulfillment [#step-8---cancel-order--cancel-fulfillment] If the order is not yet fulfilled, it may be ideal to cancel the order or cancel fulfillment to stop the order from being shipped to the customer. See [Canceling Fulfillment](#canceling-fulfillment) detail below. ### Step 9 - Dispute service resolves dispute [#step-9---dispute-service-resolves-dispute] Once the dispute is resolved, the dispute service should set the dispute resolution using the [disputesUpdate](https://developers.nextcommerce.com/docs/admin-api/reference/payments/disputesUpdate) Admin API. See [Dispute Resolutions](#dispute-resolutions) and [Resolve a Dispute](#resolving-disputes) detail below. ## Creating Disputes [#creating-disputes] To create a dispute in the store using the [disputesCreate](https://developers.nextcommerce.com/docs/admin-api/reference/payments/disputesCreate) Admin API, see example below: ```json title="__http:POST:https://{store}.29next.store/api/admin/disputes/" { "type": "alert", // dispute type "arn": "string", // optional "case_number": "string", // optional "happened_at": "2019-08-24T14:15:22Z", // date when dispute occurred "amount": "string", // dispute amount, sometimes doesnt match transaction amount "currency": "USD", // dispute currency } ``` ## Matching Disputes [#matching-disputes] To match a dispute to a transaction, pass the `transaction` id to the [disputesUpdate](https://developers.nextcommerce.com/docs/admin-api/reference/payments/disputesUpdate) API. Matching the dispute to the transaction will match the associated order and customer. ```json title="__http:PUT:https://{store}.29next.store/api/admin/disputes/{id}/" { "transaction": 7388 } ``` ### Matching Tokenized Payments [#matching-tokenized-payments] Apple Pay, Google Pay, and other tokenized payment methods present a **virtualized card number** (BIN and last 4 digits) to the payment network. Because the virtual card number differs from the cardholder's physical card, pre-chargeback alert services like Ethoca often cannot match the dispute to the transaction using the partial card number alone — these cases typically come back as "not found." When a card-based lookup returns no match, use the `auth_code` field as a fallback to search for the originating transaction. The authorization code is issued by the card issuer and remains consistent regardless of whether the payment was tokenized, making it a reliable secondary identifier. Use the [transactionsList](https://developers.nextcommerce.com/docs/admin-api/reference/payments/transactionsList) API to search transactions by `auth_code`: ```json title="__http:GET:https://{store}.29next.store/api/admin/transactions/?auth_code={auth_code}" ``` > **Note (auth_code availability):** The `auth_code` field is not supported by all payment gateways. Your app should implement a lookup strategy that falls back gracefully — for example, try card-based matching first and fall back to `auth_code`, or vice versa depending on the payment method. > > The `auth_code` and `network_transaction_id` fields were added to the Transactions API and webhook events to assist with dispute mapping. See the [changelog](https://changelog.nextcommerce.com/blog/detail/18032026/) for details. ## Creating Refunds [#creating-refunds] To create a refund for a transaction as part of the dispute resolution process, you can use the [transactionsRefundCreate](https://developers.nextcommerce.com/docs/admin-api/reference/payments/transactionsRefundCreate) Admin API. ```json title="__http:POST:https://{store}.29next.store/api/admin/transactions/{id}/refund/" { "amount": "XX.XX", // refund amount } ``` > **Note (RDR Alerts — external refunds):** RDR alerts are automatically refunded by the gateway before your app is notified. To keep the store's transaction record in sync, create the refund with `is_external: true` so the platform logs the refund without attempting to process it again. See [RDR Alerts](#rdr-alerts) for the full pattern. ## Canceling Fulfillment [#canceling-fulfillment] It's desirable to cancel fulfillment for orders that have not shipped yet when they are disputed to prevent additional losses for the merchant. > **Note:** To retrieve a list of all fulfillment orders and their status, use the [ordersFulfillmentOrdersRetrieve](https://developers.nextcommerce.com/docs/admin-api/reference/orders/ordersFulfillmentOrdersRetrieve) endpoint. **Fulfillment Status - Unfulfilled** If order `fulfilmlent_status` is `unfulfilled`, your dispute service can stop fulfillment using the [fulfillmentOrdersHold](https://developers.nextcommerce.com/docs/admin-api/reference/fulfillment/fulfillmentOrdersHold) endpoint. ```json title="__http:POST:https://{store}.29next.store/api/admin/fulfillment-orders/{id}/hold/" { "reason": "other", "reason_message": "Order disputed by customer." // Use a relevant other reason message } ``` **Fulfillment Status - Processing** If order `fulfilmlent_status` is `processing` your dispute service can request processing fulfillment orders be canceled with the fulfillment locations with the [cancellationRequestSend](https://developers.nextcommerce.com/docs/admin-api/reference/fulfillment/cancellationRequestSend) endpoint. ```json title="__http:POST:https://{store}.29next.store/api/admin/fulfillment-orders/{id}/cancellation-request/" { "message": "Order disputed by customer" // Fulfillment cancel reason } ``` > **Warning:** Fulfillment locations need to accept the cancelation request to confirm they were able to stop fulfillment on their end at. It is possible that the fulfillment order was already shipped and the fulfillment could not be stopped. ## RDR Alerts [#rdr-alerts] RDR Alerts are automatically refunded with the gateway, dispute services should log an external refund for the transaction using the [transactionsRefundCreate](https://developers.nextcommerce.com/docs/admin-api/reference/payments/transactionsRefundCreate) Admin API. Setting `is_external: true` on a refund will create the refund without attempting the refund with the gateway. ```json title="__http:POST:https://{store}.29next.store/api/admin/transactions/{id}/refund/" { "amount": "XX.XX", // refund amount "is_external": true // set for external refunds } ``` ## Dispute Resolutions [#dispute-resolutions] **Alert Resolutions** * `could_not_find_order` - You could not match the alert to an order or transaction. * `declined_or_canceled_nothing_to_do` - Customer had declined or canceled the order; no further action is necessary. * `issued_full_refund` - Issued a full refund after the dispute was created. * `issued_refund_for_remaining_amount` - Order was already partially refunded so you issued a refund for the remaining amount. * `3ds_authorized_successfully` - Order was approved by 3D Secure so the customer's bank is responsible for the dispute. * `previously_refunded_nothing_to_do` - Order was already refunded before the alert was issued; no further action is necessary. * `unable_to_refund_merchant_account_closed` - You are unable to refund the order because your merchant account has been closed. * `other` - None of the available resolutions matched the outcome of this alert. **Chargeback Resolutions** * `won` - The chargeback representment process was successful and was resolved in favor of the merchant. * `lost` - The chargeback representment process was unsuccessful. ## Resolving Disputes [#resolving-disputes] To resolve a dispute, update the dispute with the appropriate [resolution](#dispute-resolutions) for the dispute type. ```json title="__http:POST:https://{store}.29next.store/api/admin/disputes/{id}/" { "resolution": "issued_full_refund" } ``` # Testing (https://developers.nextcommerce.com/docs/testing) You can test every order flow on Next Commerce — checkout, upsells, subscriptions, webhooks — **on a live store, without moving real money and without changing any payment settings**. Test cards create tagged Test Orders that never touch a payment gateway, and Test Orders can be deleted when you're done. > **Note (No separate sandbox needed):** There is no separate sandbox environment to provision. Test cards work on live stores and live integrations, so you QA against the exact configuration that will serve real customers. ## Test Cards [#test-cards] Use these card numbers in any checkout — storefront, campaign funnel, or API-driven — to create Test Orders with no attached transactions: | Test Card Number | Expiration | CVV | Use Case | | ---------------- | --------------- | --- | ---------------------------------------------- | | 6011111111111117 | Any Future Date | Any | Test payment success flow without transaction. | | 6011000990139424 | Any Future Date | Any | Test 3DS payment flow without transaction. | Orders created this way are tagged as **Test Orders** in the dashboard, skip the gateway entirely, and are safe to create on stores with live traffic. On the Admin API, you can skip card tokenization during early integration work by using the `test_card` and `test_3ds_card` tokens directly — see the [Testing Guide](https://developers.nextcommerce.com/docs/admin-api/guides/testing-guide) for the token flow. ## Testing Checkout and Campaign Funnels [#testing-checkout-and-campaign-funnels] To QA a campaign funnel (landing → checkout → upsell → receipt) end to end, add your development domain (e.g. `localhost`) as a *development* domain in the Campaigns App so requests are authorized, then pay with a test card at checkout. The [Campaigns getting-started guide](https://developers.nextcommerce.com/docs/campaigns) walks through this, including placing a complete test order. Upsell and post-purchase flows work the same way: the test card carries through the whole funnel, so every accept/decline path can be exercised without a real charge. ## Testing Full Transaction Flows [#testing-full-transaction-flows] Test cards create orders with **no** transactions. If your integration needs realistic transaction objects — captures, declines, refunds — set up the **Test Gateway** (Settings > Payments > Add Gateway), which behaves like a real gateway and produces Test transactions, including a dedicated declined-payment card. > **Warning:** Adding the Test Gateway to your default gateway group can affect live order flows. On stores with live traffic, prefer test cards, or target the Test Gateway by ID through the API. See [Test Gateway setup](https://developers.nextcommerce.com/docs/admin-api/guides/testing-guide). ## Testing Subscriptions and Renewals [#testing-subscriptions-and-renewals] You don't have to wait calendar time to test a renewal: * Create a test subscription through the [Test Gateway](https://developers.nextcommerce.com/docs/admin-api/guides/testing-guide) (Test Gateway subscriptions can create renewal orders; test-card subscriptions cannot). * Trigger a renewal on demand with the [subscriptionsRenewCreate](https://developers.nextcommerce.com/docs/admin-api/reference/subscriptions/subscriptionsRenewCreate) endpoint, or set `next_renewal_date` to a past date and the renewal processes within about 30 minutes. Both are covered in [Subscription Management](https://developers.nextcommerce.com/docs/admin-api/guides/subscription-management). ## Testing Webhooks [#testing-webhooks] Webhook payloads mirror Admin API serializers, so the data your receiver gets matches what a GET on the same resource returns. Set up a test webhook and inspect delivery logs from the dashboard to verify your receiver, and drive events with your test order flows — see the [Webhooks overview](https://developers.nextcommerce.com/docs/webhooks) for payload structure, signature verification, and retry behavior. ## Cleaning Up [#cleaning-up] Test Orders are identifiable and deletable, so QA runs don't pollute reporting. Filter for Test Orders in the dashboard to review or remove them once you're done. # Test Order Flows (https://developers.nextcommerce.com/docs/admin-api/guides/testing-guide) Testing your integration is a critical step when developing on the Next Commerce platform. There are two distinct paths to creating Test Orders, Transactions, and Subscriptions through the Admin API or storefront checkout flow. > **Note (Card Tokenization):** Cards must be tokenized before submitting on the Admin API, see [iframe card tokenization](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/bankcard) guide. ### Test Cards [#test-cards] Test cards can be used on live stores and live integrations to create **Test Orders** with the exception they do not touch the gateway and have no attached transactions. | Test Card Number | Expiration | CVV | Use Case | | ---------------- | --------------- | --- | ---------------------------------------------- | | 6011111111111117 | Any Future Date | Any | Test payment success flow without transaction. | | 6011000990139424 | Any Future Date | Any | Test 3DS payment flow without transaction. | > **Tip:** Test cards can be used to test your live integration flows without changing any store payment settings. **Test cards are generally safe to use to test your flows.** ### Test Card Tokens [#test-card-tokens] Test card tokens can be used on the API directly without needing to tokenize the card before submitting the create order request. | Test Card Number | Use Case | | ---------------- | ---------------------------------------------- | | `test_card` | Test payment success flow without transaction. | | `test_3ds_card` | Test 3DS payment flow without transaction. | > **Tip:** Use the test card tokens before you've integrated the [iFrame Card Tokenization](https://developers.nextcommerce.com/docs/admin-api/guides/payment-methods/bankcard) to validate your API requests. ### Test Gateway [#test-gateway] The Test Gateway behaves exactly as a regular gateway, when orders are created using the `test` gateway, they also have associated Test transactions. | Test Card Number | Expiration | CVV | Use Case | | ---------------- | --------------- | --- | ------------------------------------------------------------ | | 4111111111111111 | Any Future Date | Any | Test standard payment flow with successful transaction. | | 5555555555554444 | Any Future Date | Any | Test 3DS payment flow with successful transaction. | | 4012888888881881 | Any Future Date | Any | Test standard payment declined flow with failed transaction. | #### Setup Test Gateway [#setup-test-gateway] To setup the test gateway, go to **Settings > Payments > Add Gateway** to add the Test Gateway to your store. Next, add the Test Gateway to your default gateway group or use the gateway ID directly through the Admin API. > **Warning:** The `test` gateway path requires setting up the gateway and can negatively impact your store's live order flows. **Use with caution if your store has live traffic.** ### Test Subscriptions [#test-subscriptions] Subscriptions can be created with both the [Test Gateway](#test-gateway) and [Test Cards](#test-cards), however there are some small behavior differences at this time. | Test Card Number | Expiration | CVV | Use Case | | ---------------- | --------------- | --- | --------------------------------------------------- | | 4111111111111111 | Any Future Date | Any | Test subscription can create renewal orders. | | 6011111111111117 | Any Future Date | Any | Test subscription **cannot** create renewal orders. |