---
title: "Payments API | Overview"
description: "Learn how to create payments directly using KOMOJU's Payments API. Understand Session-based and direct payment methods with step-by-step integration guidance."
url: "https://docs.priv.staging.komoju-dev.tools/en/docs/integration-guides/payments-api-overview"
source_url: "https://docs.priv.staging.komoju-dev.tools/en/docs/integration-guides/payments-api-overview.md"
language: en
last_modified: "2026-03-25"
---

> ⚠️ **Warning:** **PCI-DSS Warning**
>
> If you use this guide to process credit cards, we will likely ask you to submit proof of PCI-DSS compliance. You may be able to lessen the requirement by collecting token information client-side and using Tokens. Have a chat with your Customer Success representative for more details.
>
> The simplest way around this is to integrate with [Hosted Page](https://docs.priv.staging.komoju-dev.tools/en/docs/integration-guides/web-integrations/introduction-to-hosted-page.md) or [Hosted Fields](https://docs.priv.staging.komoju-dev.tools/en/docs/integration-guides/introduction-to-hosted-fields.md).

In this guide we'll show you how to make payments directly through KOMOJU. By directly, we mean that your server sends payment details (e.g. a credit card number) to KOMOJU, and KOMOJU processes it immediately.

Some possible use cases for this style of integration might be:

- You have a fully custom UI for collecting customer payment details, and want to use KOMOJU behind the scenes.
- You have contracts with multiple payment service providers, including KOMOJU, and want to multiplex between them.

When using our API to create payments, you have 2 options. Either you can first create a [Session](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/sessions/POST/sessions) and then "pay" for it, or you can just create a [Payment](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/payments/GET/payments) directly. Usually the first method is the most versatile but we'll walk through both methods for completeness.

# Method 1: Pay for a Session

This method of creating payments requires at least 2 API calls: one to create a [Session](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/sessions/POST/sessions) object and one to create a [Payment](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/payments/GET/payments).

| ✅ Advantages | ❌ Disadvantages |
| --- | --- |
| Works with 3DS out of the box. | Requires at least 2 API calls. |
| Can have multiple payment attempts for one order number. |  |
| Can send line items to KOMOJU for better fraud detection and bookkeeping. |  |
| Can supply shipping and billing address for improved fraud detection. |  |
| Can easily avoid PCI-DSS burden by calling "pay" on frontend. |  |

We'll go over the steps in detail below.

## Step 1: create a session

Call the [Session: Create](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/sessions/POST/sessions) API with the following attributes:

| Authentication | Method | Endpoint |
| --- | --- | --- |
| Secret key | POST | https://komoju.com/api/v1/sessions |

*** = required**

| Request Attribute | Type | Description |
| --- | --- | --- |
| `amount` * | integer | Integer amount of money. This is always in the lowest possible denomination for the given currency. For example, an `amount` of 1 could mean 1 yen, or 1 US cent. |
| `currency` * | string | 3-letter currency identifier. Examples might be "USD" or "JPY. |
| `return_url` | string | URL to redirect the customer back to your website or app. Not strictly required, but highly recommended. |
| `payment_data[external_order_num]` | string | Your system's order number. This must be unique per session. |
| `payment_data[capture]` | enum | "auto" or "manual". Defaults to "auto". Setting this to "manual" will initiate [Two-Step Capture](https://docs.priv.staging.komoju-dev.tools/en/docs/development/advanced-payments/two-step-payments.md). |
| `email` | string | Customer's email address. If this is present on the Session, `payment_details[email]` becomes optional. |
| `name` | string | Customer's name. |
| `line_items` | array of object | List of line items. See [Session: Create](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/sessions/POST/sessions) for precise format. |
| `metadata` | object | Key-value pairs for your own internal use. For example, if you don't like our uniqueness validation on order number, you can put your order numbers in here. Any [Payments](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/payments/GET/payments) created by this session will inherit its `metadata`. |

The resulting Session object can be quite large. The attributes you'll care about depend on how you plan to use the session. In this case, we're just using the session as a carrier for payments, so these are the response attributes of interest:

| Response Attribute | Type | Description |
| --- | --- | --- |
| `id` | string | Unique identifier for the Session. You'll need this for subsequent API calls. |
| `payment_methods` | array of object | List of payment methods supported by the session. |
| `payment_methods[i].type` | string | Type slug corresponding to a payment type in [Payment Details](https://docs.priv.staging.komoju-dev.tools/en/docs/integration-guides/payments-api-payment-details.md). |

## Step 2: pay for the session

Next, you'll want to call our [Session: Pay](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/payments/POST/payments) endpoint.

| Authentication | Method | Endpoint |
| --- | --- | --- |
| Secret or publishable key | POST | https://komoju.com/api/v1/sessions/{id}/pay |

*** = required**

| Request Attribute | Type | Description |
| --- | --- | --- |
| `payment_details` * | object | An object representing the user input required for your specific payment method of choice. See [Payment Details](https://docs.priv.staging.komoju-dev.tools/en/docs/integration-guides/payments-api-payment-details.md). |
| `fraud_details` | object | Information about the customer's current browsing context. See [Fraud Details](https://docs.priv.staging.komoju-dev.tools/en/docs/integration-guides/payments-api-fraud-details.md). |
| `capture` | enum | "auto" or "manual", defaults to "auto". This overrides the value specified during Session creation. |

## Step 3: handle the pay result

The response from [Session: Pay](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/sessions/POST/sessions/%7Bid%7D/pay) looks like this:

| Response Attribute | Type | Description |
| --- | --- | --- |
| `status` | enum | "completed", "pending", or "error" |
| `redirect_url` | string | URL to redirect your customer to for next steps. More on this soon. |
| `payment` | object | Payment object, same format as the response to [Payment: Show](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/payments/GET/payments/%7Bid%7D). You can use this to access the response [Payment Details](https://docs.priv.staging.komoju-dev.tools/en/docs/integration-guides/payments-api-payment-details.md) object. |

If `status` is _not_ "error", then you can always handle this by redirecting your customer to `redirect_url`.

Here's a detailed breakdown of some different scenarios you might encounter here. When in doubt, just redirect to `redirect_url`.

| `status` | `capture` | `payment.status` | What this means | What you can do |
| --- | --- | --- | --- | --- |
| "error" | * | N/A | Likely invalid input, like a wrong credit card number. | Ask the customer to try again. You may call [Session: Pay](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/sessions/POST/sessions/%7Bid%7D/pay) again on the same session. |
| "completed" | "auto" | "captured" | Payment was successful. | Redirect to `redirect_url`. Alternatively, you may simply show "thanks for your order". |
| "completed" | "auto" | "authorized" | Submission successful, awaiting customer action. | Redirect to `redirect_url`. It will point to payment instructions. Alternatively, manually show instructions (see [Payment Details](https://docs.priv.staging.komoju-dev.tools/en/docs/integration-guides/payments-api-payment-details.md)). |
| "completed" | "manual" | "authorized" | Payment successfully authorized ([Two-Step Capture](https://docs.priv.staging.komoju-dev.tools/en/docs/development/advanced-payments/two-step-payments.md)) | Redirect to `redirect_url`. Alternatively, you may show "thanks for your order". Later, you will want to call [Payment: Capture](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/payments/POST/payments/%7Bid%7D/capture) on the resulting payment. |
| "pending" | * | "pending" | User must log in to an external service to pay. | Redirect to `redirect_url`. It will lead to either a payment app (e.g. PayPay), or a credit card 3D Secure login page. If credit card, you may render `redirect_url` in an iframe. |

If you choose to _not_ redirect to `redirect_url` in any of these cases, we recommend reading through the [Payment Details](https://docs.priv.staging.komoju-dev.tools/en/docs/integration-guides/payments-api-payment-details.md) doc to understand how your specific payment method(s) works.

## Step 4: handle return URL and webhook

The `return_url` you specified when you created your session is where the customer will be sent when they finish submitting their payment information, or when they decide to cancel while on their payment app.

When the customer is redirected to `return_url`, a query parameter called `session_id` will be appended. Your back-end should use this `session_id` to call [Session: Show](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/sessions/GET/sessions/%7Bid%7D), and check the Session's `status`.

Here's an example:

| Original `return_url` | URL that customer gets redirected to |
| --- | --- |
| https://example.com/order/abc | https://example.com/order/abc?session_id=63r9bjkqklasnofxttq7z9abc |

In addition to this `return_url` check, we recommend you set up [Webhooks](https://docs.priv.staging.komoju-dev.tools/en/docs/introduction/webhooks.md) - specifically for `payment.captured` and `payment.authorized`. You can use the Payment's `external_order_num`, `metadata`, or `session` attributes to associate it with your order.

---

# Method 2: Creating a Payment Directly

Here's how you can create payments without an associated Session.

| ✅ Advantages | ❌ Disadvantages |
| --- | --- |
| In some cases, can complete payment in only 1 API call. Might be simpler for your use-case. | Skips 3DS by default for credit card. See [3D Secure Without a Session](https://docs.priv.staging.komoju-dev.tools/en/docs/integration-guides/payments-api-3ds.md). |
|  | Order number must be unique per payment; awkward to represent multiple attempts for one order. |
|  | Requires special case code for each payment type. Harder to build a "one size fits all" integration that works with many payment methods. |

## Step 1: create payment

Call [Payment: Create](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/payments/POST/payments).

| Authentication | Method | Endpoint |
| --- | --- | --- |
| Secret key | POST | https://komoju.com/api/v1/payments |

*** = required**

| Request Attribute | Type | Description |
| --- | --- | --- |
| `amount` * | integer | Integer amount of money. This is always in the lowest possible denomination for the given currency. For example, an `amount` of 1 could mean 1 yen, or 1 US cent. |
| `currency` * | string | 3-letter currency identifier. Examples might be "USD", or "JPY". |
| `return_url` | string | A URL for the customer to return to once they finish paying. This is optional for credit card payments. |
| `capture` | boolean | Set to `false` if you want to perform [Two-Step Capture](https://docs.priv.staging.komoju-dev.tools/en/docs/development/advanced-payments/two-step-payments.md). |
| `tax` | integer | Set this to 0. The default is "auto" which is always 10% of your `amount`. |
| `external_order_num` | string | Your system's order number. You can use this to associate KOMOJU payments with your own internal orders. This must be unique. |
| `metadata` | object | Arbitrary key-value pairs for your internal use. For example, you can put your order number in here if our uniqueness validation on `external_order_num` causes problems. |
| `payment_details` | object | An object containing payment method-specific attributes (see [Payment Details](https://docs.priv.staging.komoju-dev.tools/en/docs/integration-guides/payments-api-payment-details.md)). |

See the [Payment: Create](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/payments/POST/payments) reference for the full list. Most of the time, the attributes you see here are the only ones you'll need.

## Step 2: handle the response

The [Payment: Create](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/payments/POST/payments) endpoint returns a Payment object with the following attributes (non-exhaustive):

| Response Attribute | Type | Description |
| --- | --- | --- |
| `id` | string | Unique Payment ID, used for performing further actions like [Payment: Capture](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/payments/POST/payments/%7Bid%7D/capture). |
| `status` | string | Tells you whether or not the payment is paid. More on this soon. |

Here's a breakdown of the different Payment `status` values you might encounter:

### pending

Payment has been initiated but not confirmed. The response should have a `payment_details.redirect_url`. Send your customer to that URL, then listen for `payment.captured` webhooks.

### authorized

Two possible meanings, depending on the type of payment.

1. For long-form async payment methods (konbini, bank_transfer, payeasy), authorized payments are reserved but awaiting customer action (e.g. waiting for customer to go to the store and pay cash). This can take several days. You'll get a `payment.captured` webhook if/when the customer pays. Otherwise you will get a `payment.expired` webhook.
2. For all other payment methods, authorized refers to [Two-Step Capture](https://docs.priv.staging.komoju-dev.tools/en/docs/development/advanced-payments/two-step-payments.md). This is where the funds are in your control, but haven't left the customer's account yet. These authorized payments are awaiting merchant action (e.g. merchant performs a manual capture when goods are shipped). You can call [Payment: Capture](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/payments/POST/payments/%7Bid%7D/capture) to capture authorized funds, or [Payment: Cancel](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/payments/POST/payments/%7Bid%7D/cancel) to void the authorization.

### captured

Payment was successful. The money will be transferred to your bank account next settlement.

### refunded

The payment was completed, but has been fully refunded. Note that partially refunded payments remain captured. You'll never see this status in the response of [Payment: Create](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/payments/POST/payments) or any brand new payment. It only occurs after you (the merchant) call [Payment: Refund](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/payments/POST/payments/%7Bid%7D/refund) or click the refund button on the komoju.com dashboard.

### cancelled

Either the customer decided to cancel payment, or you (the merchant) called [Payment: Cancel](https://docs.priv.staging.komoju-dev.tools/en/api-reference#2025-01-28/tag/payments/POST/payments/%7Bid%7D/cancel).

### expired

Payment was pending or authorized with no action for too long.

## Note on handling Konbini / Convenience Store Payments

Konbini payments may have the following fields in the response:

- `instructions_url` (All Konbini): This contains a URL to a page providing the required payment information as well as detailed instructions on how to perform the payment at the Konbini. It should be served to the end-user for their convenience.
- `receipt`: This is a payment code that can be used for Konbini purchases.
- For 7-Eleven, this is deprecated. This field should not be served to the end-user. The end user is required to access the URL served in the `instructions_url` field to perform payment at the store.
- For others, this can be provided to end users along with `confirmation_code`, if available in the response. However, we strongly recommend providing just the URL from `instructions_url` to the end user, as it contains precise instructions as to how to perform payment at the store.
- `confirmation_code`: This is available for some Konbini brands and can be used by end users to perform payment at the store, in combination with `receipt`. However, this is not recommended - like `receipt`, we recommend providing just the URL from `instructions_url` to the end-user, as it contains precise instructions as to how to perform payment.

## Step 3: webhook

The definitive way to know when a payment has been captured is to listen for `payment.captured` [Webhooks](https://docs.priv.staging.komoju-dev.tools/en/docs/introduction/webhooks.md). We recommend putting your order processing logic into your webhook handler for `payment.captured` or `payment.authorized`.

# Notes on return_url

For direct payments, when the customer redirects to your return_url, KOMOJU adds query parameters to the url. One such query parameter an HMAC that can be checked to verify that the redirect came from KOMOJU.

The HMAC is computed using the final part of the URL: the path and all the query params other than the HMAC itself, signed using your private key. So, for example if the return URL provided at payment creation is:

```
https://example.com/return

```

After a payment is completed, we will redirect to the following URL:

```
https://example.com/return?hmac=examplehmac&param1=a&param2=b

```

The message is the path + parameters with hmac removed, so in this case:

```
message = "/return?param1=a&param2=b"

```

Then you can calculate the HMAC using `hmac-sha256` to verify that it matches our HMAC. Example Ruby code below:

```ruby
OpenSSL::HMAC.hexdigest('sha256', your_private_key, message) => "examplehmac"

```
