# Direct API integration

> Submit card data or tokens directly from your server through the create direct transaction API, handle 3DS redirects yourself, and rely on webhooks for the final results of payments, tokenization, subscriptions, and pre-authorizations.

With the Direct API integration you build your own payment page and call [Create direct transaction](/payments/api-reference/endpoints/direct-create-transaction) from your server: card data or tokens are submitted by your backend, 3DS redirects are handled by you, and the final result is confirmed through webhooks. Unlike Checkout and the Web SDK, card data passes through your systems, so this integration requires PCI DSS compliance. In return you get a fully custom payment experience and direct server-side control over tokenization, token payments, subscription billing, and pre-authorization. Setup and method-specific flows for Apple Pay, Google Pay, and each local payment method on the Direct API are covered in [Payment methods](/payments/online-payments/payment-methods).

## Before you begin

Before you begin, follow [Setup](/payments/get-started/setup) to obtain your API credentials and add your server's public outbound IP addresses to the allowlist for the target environment. Generate `sign` for each request according to [Request signing](/payments/get-started/request-signing). Before going live, follow [Sandbox testing](/payments/get-started/testing) to verify all scenarios used by your integration in the sandbox.

The Direct API integration additionally requires **PCI DSS compliance**: to collect card numbers, expiry dates, and CVC on your own page and submit them to Onerway, you must hold a valid PCI DSS certification, transmit cardholder data over TLS, and never store sensitive authentication data such as CVC. If you are not certified, use [Checkout integration](/payments/online-payments/checkout) or [Web SDK integration](/payments/online-payments/sdk) instead — card data never reaches your server. Subscription renewals and pre-authorization captures do not submit card data and are not subject to this requirement; a card token payment still submits `cardInfo.cvv` and therefore remains within scope.

## Integration flow

<steps level="3">

### Create a transaction on your server

Call [Create direct transaction](/payments/api-reference/endpoints/direct-create-transaction). The transaction model is defined by the [`productType` field](/payments/api-reference/endpoints/direct-create-transaction#request-productType), the [`subProductType` field](/payments/api-reference/endpoints/direct-create-transaction#request-subProductType), and the [`txnType` field](/payments/api-reference/endpoints/direct-create-transaction#request-txnType) together. For a direct card payment with card details collected by you, submit `productType=CARD`, `subProductType=DIRECT`, and `txnType=SALE`, with the card data in the [`cardInfo` field](/payments/api-reference/endpoints/direct-create-transaction#request-cardInfo).

The [`txnOrderMsg` field](/payments/api-reference/endpoints/direct-create-transaction#request-txnOrderMsg) must include `returnUrl` (the synchronous return address for 3DS and other redirect flows) and `notifyUrl` (the webhook notification address). Unlike Checkout, the Direct API expects you to collect browser, device, and cardholder IP data (such as `transactionIp`) and submit them in `txnOrderMsg`; see the [`txnOrderMsg` field tree](/payments/api-reference/endpoints/direct-create-transaction#request-txnOrderMsg) for the exact requirement of each sub-field.

### Handle the redirect based on the response status

Onerway decides whether 3DS authentication is needed, and the [`status` field](/payments/api-reference/endpoints/direct-create-transaction#response-data-status) in the synchronous response may already be terminal:

| Response | Handling |
| --- | --- |
| `status=S` | The payment succeeded; complete the order after the webhook arrives. |
| `status=R` with `actionType=RedirectURL` | Redirect the customer's browser to the [`redirectUrl` field](/payments/api-reference/endpoints/direct-create-transaction#response-data-redirectUrl) to complete 3DS authentication or the local payment method page. |
| Other values | Handle failed or processing states according to `status` and `respCode`; see the API Reference for all values. |

Native apps can load `redirectUrl` in a WebView, watch for navigation to `returnUrl`, close the WebView, and query the result from the server.

### Handle the synchronous return

After authentication the customer returns to your page through `returnUrl`. The return is for page flow only and is not guaranteed to carry transaction parameters: add your order ID to `returnUrl`, show the customer a "processing" state when they return, and verify on your server through [Query transactions](/payments/api-reference/endpoints/query-transactions). Do not use any parameter on the return URL to drive order processing.

### Confirm the result through webhooks

Onerway POSTs the final result to `notifyUrl`. See [Confirm the payment result](#confirm-the-payment-result) for signature verification, acknowledgement, retries, and idempotency.

</steps>

## Tokenization and token payments

The Direct API flow for saving a payment method is: submit card data from your server to create a token, then pay with the `tokenId`, and [list](/payments/api-reference/endpoints/list-saved-tokens) or [delete](/payments/api-reference/endpoints/delete-card-token) saved records as needed. Choosing between customer opt-in and server-side tokenization, and the distinction between the three kinds of tokens, are covered in [Saved payment methods](/payments/online-payments/scenarios/saved-payment-methods).

1. **Create a card token**: call [Create card token](/payments/api-reference/endpoints/create-card-token) with the card data and a stable [`merchantCustId` field](/payments/api-reference/endpoints/create-card-token#request-merchantCustId), together with `notifyUrl` and `returnUrl`. When the response [`status` field](/payments/api-reference/endpoints/create-card-token#response-data-status) is `R`, redirect the cardholder to `redirectUrl` to complete 3DS authentication.
2. **Confirm the saved result**: the [saved payment method result webhook](/payments/api-reference/webhooks/payment-method-result) (`txnType=BIND_CARD`) is the final source of truth — store the `tokenId` only when `status=S`. Neither the return to `returnUrl` nor the synchronous response means the payment method was saved. You can also verify with [List saved tokens](/payments/api-reference/endpoints/list-saved-tokens).
3. **Make a token payment**: call [Create direct transaction](/payments/api-reference/endpoints/direct-create-transaction) with `subProductType=TOKEN` and the [`tokenInfo` field](/payments/api-reference/endpoints/direct-create-transaction#request-tokenInfo) (`tokenId` set to the card token returned earlier, `provider` omitted), submitting the CVC the customer enters for this purchase in `cardInfo.cvv` and the same `merchantCustId` used when the token was created. A token payment may also return `status=R` and require 3DS authentication; handle it as described in the integration flow.
4. **Manage saved tokens**: [List saved tokens](/payments/api-reference/endpoints/list-saved-tokens) returns the `id` and `tokenId` of each binding record. When a customer asks to remove a card, call [Delete card token](/payments/api-reference/endpoints/delete-card-token) with the binding record `id` — not the `tokenId`.

Additional considerations for the Direct API integration: both creating a card token and making a token payment handle card data (a token payment must submit `cardInfo.cvv`), so both steps require PCI DSS. If you are not certified, keep both saving the card and repeat purchases on the Checkout or Web SDK page.

## Subscriptions

Choosing between managed and self-managed subscriptions, contract credentials, and lifecycle notifications are covered in [Subscription payments](/payments/online-payments/scenarios/subscriptions). This section explains how to make the calls on the Direct API once you have chosen. All three request types use [Create direct transaction](/payments/api-reference/endpoints/direct-create-transaction) with `subProductType=SUBSCRIBE` and the [`subscription` field](/payments/api-reference/endpoints/direct-create-transaction#request-subscription), distinguished by [`subscription.requestType`](/payments/api-reference/endpoints/direct-create-transaction#request-subscription-requestType):

| `requestType` | Purpose | Key input |
| --- | --- | --- |
| `0` | Initial subscription, creating the contract | `cardInfo` or `tokenInfo`, `merchantCustId`, `selfExecute`, billing frequency and cycle count |
| `1` | Billing for the current cycle of a self-managed subscription | `contractId`, `tokenId`, `merchantCustId`, the amount for this cycle |
| `2` | Managed subscription plan upgrade or downgrade | `contractId`, `tokenId`, `changeMode`, `prorationMode` |

After the **initial subscription** succeeds, store the `contractId` and `tokenId` from the [subscription payment webhook](/payments/api-reference/webhooks/subscription-payment). The initial subscription can also be completed through Checkout or the Web SDK — later billing and updates still go through the Direct API.

**Self-managed subscription renewal** (`requestType=1`) submits `contractId`, `tokenId`, `merchantCustId`, and the amount for this cycle, with no card data, so renewals carry no PCI DSS requirement.

**Managed subscription plan updates** (`requestType=2`) use the stored `contractId` and `tokenId`; when the change takes effect is controlled by the [`subscription.changeMode` field](/payments/api-reference/endpoints/direct-create-transaction#request-subscription-changeMode), and `prorationMode` controls whether the prorated amount is calculated by remaining days or submitted by you in `proration`.

Additional considerations for the Direct API integration: when a managed card subscription also submits `subscription.bindCard=true`, you receive a [saved payment method result webhook](/payments/api-reference/webhooks/payment-method-result) and a subscription payment webhook with different `transactionId` values; handle each idempotently.

## Pre-authorization

A pre-authorization holds the order amount on the cardholder's card without charging it immediately. On the Direct API, `txnType=AUTH` applies to direct card payment and token payment (`subProductType=DIRECT` or `TOKEN`); it does not apply to local payment method, subscription, or installment transactions.

Call [Create direct transaction](/payments/api-reference/endpoints/direct-create-transaction) with `txnType=AUTH`; the remaining parameters are the same as a direct card or token payment. When 3DS is required, handle the `status=R` redirect as usual. Store the `transactionId` and `paymentId` from the response; capture or void later through [Capture or void authorization](/payments/api-reference/endpoints/capture-or-void-authorization).

The lifecycle from authorization to capture or void, notifications, boundaries, and status handling are covered in [Pre-authorization and capture](/payments/online-payments/scenarios/pre-authorization).

## Local payments

A local payment method shares the create direct transaction API with card payment; only the parameter combination and flow shape differ. Set the [`productType` field](/payments/api-reference/endpoints/direct-create-transaction#request-productType) to the local payment method scope value and submit the [`lpmsInfo` field](/payments/api-reference/endpoints/direct-create-transaction#request-lpmsInfo) (`lpmsType` selects the payment method; the remaining child fields are conditionally required per method), submitting `DIRECT` in `subProductType` for one-off payments and `SUBSCRIBE` for subscriptions. A local payment method does not support `txnType=AUTH`. Finding the supported methods and checking availability, handling the redirect and delayed settlement, method-specific parameters, and subscription behavior are covered in [Local payment methods](/payments/online-payments/payment-methods/local-payment-methods).

Additional considerations for the Direct API integration: `productType=ALL` is an aggregated Checkout display concept and is not supported by the Direct API, so you build the method list yourself and handle the customer action returned under `status=R` as well as the return to your page.

## Profit sharing

Profit sharing applies to the platform model: the platform merchant creates the payment with the receiving sub-merchant's `merchantNo`, and the payment is eligible for profit sharing only when you submit the [`paymentMethodOptions` field](/payments/api-reference/endpoints/direct-create-transaction#request-paymentMethodOptions) with `profitShare=true` in its `share` object; the remaining parameters are the same as an ordinary transaction. When you also set `profitShareRate`, Onerway allocates funds automatically after a successful `SALE` or `CAPTURE`; without it, your server initiates profit sharing through the API. To receive automatic profit share and reversal notifications, also set `profitShareNotifyUrl`. Submit `paymentMethodOptions` as a JSON string as required by the API.

Choosing between automatic and API-initiated profit sharing, result notifications, queries, and reversals are covered in [Profit sharing](/payments/online-payments/scenarios/profit-sharing).

## Confirm the payment result

The final result of a Direct API integration is determined by webhooks; the payload for each scenario is documented in the [payment result webhook](/payments/api-reference/webhooks/payment-result), the [saved payment method result webhook](/payments/api-reference/webhooks/payment-method-result), the [subscription payment webhook](/payments/api-reference/webhooks/subscription-payment), and the [authorization, capture, and void webhook](/payments/api-reference/webhooks/authorization-capture). Signature verification, acknowledgement and retries, deduplication, status interpretation, and query fallback follow the shared rules in [Webhooks](/payments/get-started/webhooks).

Additional considerations for the Direct API integration: this integration uses all four notification types, so your webhook endpoint must accept every notification type involved in the scenarios you use. Tokenization, subscription-with-binding, and pre-authorization flows with a later capture or void produce several related notifications with different `transactionId` values — associate them through `paymentId` and `contractId`. The synchronous response may already return the terminal `status=S`; still wait for the webhook before completing the order. If the customer has returned but no webhook has arrived, fall back to [Query transactions](/payments/api-reference/endpoints/query-transactions).

## Go-live checklist

- You hold a valid PCI DSS certification; the payment page uses TLS and never stores CVC.
- `status=R` redirects and `returnUrl` returns are handled, and your server queries the transaction after the return instead of trusting URL parameters.
- Your webhook endpoint passes the [Webhooks go-live checklist](/payments/get-started/webhooks#go-live-checklist) and accepts every notification type used by your scenarios, including tokenization, subscription, and pre-authorization.
- Stored `tokenId`, `contractId`, and `paymentId` values are kept as strings and associated with the customer or order.
- The sandbox run covers the 3DS Challenge flow, the 3DS Frictionless flow, and every tokenization, subscription, pre-authorization, and local payment scenario you use.
