Creating Payments
Learn how to send customer payment info directly to us.
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 or Hosted Fields.
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 and then "pay" for it, or you can just create a Payment 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 object and one to create a Payment.
✅ 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. |
This recipe shows a complete example. We'll go over the steps in detail here.
Step 1: create a session
Call the Session: Create API with the following attributes:
Authentication | Method | Endpoint |
---|---|---|
Secret key | POST | https://komoju.com/api/v1/sessions |
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. |
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 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 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. |
Step 2: pay for the session
Next, you'll want to call our Session: Pay endpoint.
Authentication | Method | Endpoint |
---|---|---|
Secret or publishable key | POST | https://komoju.com/api/v1/sessions/{id}/pay |
Request Attribute | Type | Description |
---|---|---|
payment_details * | object | An object representing the user input required for your specific payment method of choice. See Payment Details. |
fraud_details | object | Information about the customer's current browsing context. See Fraud Details. |
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 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. You can use this to access the response Payment Details 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 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). |
"completed" | "manual" | "authorized" | Payment successfully authorized (Two-Step Capture) | Redirect to redirect_url .Alternatively, you may show "thanks for your order". Later, you will want to call Payment: 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 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, 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 - 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. |
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.
Authentication | Method | Endpoint |
---|---|---|
Secret key | POST | https://komoju.com/api/v1/payments |
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. |
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). |
See the Payment: Create 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 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. |
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:
Payment status | Meaning |
---|---|
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. 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 to capture authorized funds, or Payment: 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. |
cancelled | Either the customer decided to cancel payment, or you called Payment: Cancel. |
expired | Payment was pending or authorized with no action for too long. |
How you handle this depends on your specific use case and which payment method you chose. Advice on handling specific payment methods can be found on the Payment Details page.
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 frominstructions_url
to the end user, as it contains precise instructions as to how to perform payment at the store.
- 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
confirmation_code
: This is available for some Konbini brands and can be used by end users to perform payment at the store, in combination withreceipt
. However, this is not recommended - likereceipt
, we recommend providing just the URL frominstructions_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. 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¶m1=a¶m2=b
The message is the path + parameters with hmac removed, so in this case:
message = "/return?param1=a¶m2=b"
Then you can calculate the HMAC using hmac-sha256
to verify that it matches our HMAC. Example Ruby code below:
OpenSSL::HMAC.hexdigest('sha256', your_private_key, message) => "examplehmac"
Updated 3 months ago