Introduction
The Paidy API is exposed over a series of REST endpoints, with request and response data formatted as JSON (Content-Type: application/json). Each request is authenticated using your API Key and a checksum unique to the request data.
The Paidy API uses common HTTP response codes, such as 200 - OK, 400 - Bad Reqeuest and 401 - Unauthorized, to indicate the general result of the request. Where the response contains JSON data, a string attribute named “status” provides the exact result of the request.
What is a Paidy Payment?
We have structured Paidy to emulate the typical credit card payment. A payment consists of one Authorization and one or more Captures. Where Paidy is different is:
- Instead of a credit card number the consumer uses their email address and phone number
- There’s no signup to get a Paidy account and there’s no application to use Paidy. Everyone today already has a Paidy account ready for them to use.
When you perform a valid Authorization a Paidy Payment is created and a Payment ID returned in the response. The Payment ID is a token which you can then use to perform other actions on the Payment, such as Capture, Refund and Status.
Authorization
All Paidy Payments start with an Authorization request. The request contains the consumer and order data on which the authorization is assessed. Each request is analyzed by our proprietary fraud and credit assessment systems.
The vast majority of requests are processed within five seconds but some may take up to 30 seconds. If the request is approved Paidy is guaranteeing that payment to you the merchant. It’s important to note that a successful authorization doesn’t mean the consumer is charged yet. To charge the consumer you must perform a Capture request using the Payment ID from the authorization result, after which the payment will be pushed to the consumer’s Paidy Bill.
An Authorization Result contains the status of the authorization (if it was successful or failed) and additional data such as when the authorization expires. By default, we automatically expire authorizations after 30 days.
Capture
When you’re ready to capture a payment you are effectively redeeming Paidy’s promise to charge the consumer. Any payment that is open (has a successful authorization and has not expired) can be captured. You can choose to capture the entire payment or just parts of the order in the payment.
We recognize that you know best when to capture a payment. You can choose to capture immediately after an authorization, or you can wait until the order has shipped to the consumer’s address. When a payment has been fully captured (all items have been captured) the payment is automatically closed.
Paidy Checkout
The Paidy Checkout is a Javascript application that you can import in to your checkout page to handle the authorization flow instead of implementing it yourself, saving you time. The biggest benefit is that we’ve optimized the Paidy Checkout for higher consumer conversion and we continue to do this on a daily basis. The result is that with the Paidy Checkout, you know we’re working every day to improve your cart conversion rates.
The consumer never leaves your checkout page with Paidy Checkout, so you don’t need to worry about session management, redirects or lost sales. The Paidy Checkout supports all major web browsers, mobile phones and tablets.
When you configure the Paidy Checkout you pass it a callback function that you use to submit your existing checkout webform after a successful authorization. Just like directly implementing the authorization API you get back a Payment ID that you can then use in your backend code to capture.
The Result object
All endpoints share a common Result object
Parameter | Required | Description |
---|---|---|
payment_id | optional | If a payment exists the Payment ID is returned |
status | required | Result code |
reason | optional | Reason code for result |
message | optional | Additional description |
link | optional | Follow this to see the developer documentation |
Common status code for all endpoints
StatusCode | Meaning |
---|---|
bad_request | HTTP request was malformed or missing JSON arguments |
request_failed | HTTP request OK but request rejected (usually bad checksum, or rates limit reached) |
internal_error | Try again later |
Authentication
All API request are authenticated. There are three parts to request authentication:
- API Key: This is your public key that identifies you as a merchant
- Checksum: Each request has a checksum JSON attribute that can only be generated using your secret key
- Auth Code: For some Payments we send the consumer a PIN code to their phone.
Your API Key is added as the Authorization HTTP request header prefixed with “Bearer ”, like the following:
Authorization: Bearer NTNlYAY0MDFjYTAxMyBlNDAzNDk2ZDE3
The method of generating the request checksum depends on the endpoint of the request. It typically involves concatenating string values within the request and prefixing your Secret Key, the calculating the SHA256 hash value on the string. The SHA256 value can either be represented as a Base64 or Hex string; both are accepted.
When we determine that a Payment requires additional authentication we will send an SMS pin code to the consumer’s phone and return a authenticate_consumer
status. This applies only to Authorizations. Provide an input for the consumer to enter the pin code and try the authorization again, adding the code to the auth_code argument of the request object.
Reactive
We’re Reactive, not blocking and immutable. Everything we do here at Paidy follows the Reactive Manifesto. This applies to our API and in particular the immutable nature of the API.
When an endpoint requires additional data, such as a pin code from the consumer for an authorization, or when updating an existing Payment, you need to send all the data, not just that which has changed or been requested.
API Endpoints
Authorize
Example:
curl "https://api.paidy.com/pay/authorize" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer NTNlYAY0MDFjYTAxMyBlNDAzNDk2ZDE3" \
-d '{ \
"buyer": { \
"name": "山田 太郎", \
"name2": "ヤマダ タロウ", \
"dob": "1988-01-15", \
"email": { \
"address": "taro.yamada@paidy.com" \
}, \
"address": { \
"address1": "3-16-26", \
"address2": "六本木", \
"address3": "港区", \
"address4": "東京都", \
"postal_code": "106-0032" \
}, \
"phone": { \
"number": "03-4453-3234" \
} \
}, \
"order": { \
"items": [{ \
"item_id": "1", \
"title": "アディダススニーカー", \
"amount": 1000, \
"quantity": 1 \
},{ \
"item_id": "2", \
"title": "ナイキスニーカー", \
"amount": 1500, \
"quantity": 1 \
}], \
"tax": 300, \
"shipping": 500, \
"total_amount": 4800 \
}, \
"merchant_data": { \
"store": "Test Store", \
"customer_age": 400, \
"last_order": 215, \
"last_order_amount": 3500, \
"known_address": false, \
"ltv": 12500 \
}, \
"checksum": "2P0GS+O1W49HP4IQA3uhjb2Q/ans+zEEYHjT3YCJHho=", \
"tracking": { \
"consumer_ip": "0.0.0.0" \
} \
}'
import paidy
api = paidy.authorize('checksum')
api.paidy.post()
The above command sends a JSON like below:
{
"buyer": {
"name": "山田 太郎",
"name2": "ヤマダ タロウ",
"dob": "1988-01-15",
"email": {
"address": "taro.yamada@paidy.com"
},
"address": {
"address1": "3-16-26",
"address2": "六本木",
"address3": "港区",
"address4": "東京都",
"postal_code": "106-0032"
},
"phone": {
"number": "03-4453-3234"
}
},
"order": {
"items": [{
"item_id": "1",
"title": "アディダススニーカー",
"amount": 1000,
"quantity": 1
},{
"item_id": "2",
"title": "ナイキスニーカー",
"amount": 1500,
"quantity": 1
}],
"tax": 300,
"shipping": 500,
"total_amount": 4800
},
"merchant_data": {
"store": "Test Store",
"customer_age": 400,
"last_order": 215,
"last_order_amount": 3500,
"known_address": false,
"ltv": 12500
},
"checksum": "2P0GS+O1W49HP4IQA3uhjb2Q/ans+zEEYHjT3YCJHho=",
"tracking": {
"consumer_ip": "0.0.0.0"
}
}
The above command returns JSON structured like this:
{
"payment_id":"542e6dc61200008a077a4de3",
"status":"authorize_success",
"test":false
}
Create a Payment to charge a consumer
To charge a consumer you first perform an authorization request. If the authorization is successful you can use the resulting Payment ID to capture the amount.
HTTP Request
POST https://api.paidy.com/pay/authorize
Query Parameters
Parameter | Required | Description |
---|---|---|
buyer | required | Consumer details such as name, email, phone |
buyer name | required | Consumer name |
buyer name2 | required | Alternative name representation |
buyer dob | optional | Date of birth |
buyer email | required | |
buyer email address | required | Email address |
buyer phone | required | Phone |
buyer phone.number | required | Phone number |
buyer address | required | Physical address |
buyer address address1 | optional | House/Apartment/Room plus number and addition |
buyer address address2 | required | Street Address |
buyer address address3 | required | City |
buyer address address4 | required | State/Province/County/Prefecture |
buyer address postal_code | required | Post or zip code |
order | required | Purchase data including the items, quantity and amounts |
order items | required | Order/Cart/Basket data |
order items.item item_id | optional | Defaults to a sequence integer |
order items.item title | required | Description of the product |
order items.item amount | required | Single item price |
order items.item quantity | required | Quantity of this product |
order tax | optional | Tax amount for this order |
order shipping | optional | Shipping cost for this order |
order total_amount | required | Total payment amount |
order order_ref | optional | merchant’s own reference |
merchant_data | required | Merchant shared data |
merchant_data store | required | Merchant branding |
merchant_data customer_age | required | Number of days since first purchase |
merchant_data last_order | required | Number of days since last purchase |
merchant_data last_order_amount | required | Value of last order |
merchant_data known_address | required | If shipped to this address before |
merchant_data ltv | required | Lifetime value of this customer |
tracking | required | Session information, such as consumer’s IP address |
tracking consumer_ip | required | IP address of customer |
options | optional | Options to configure the Payment |
options authorize_type | optional | Type of request (Simple or Extended) |
options num_payments | optional | Split over number of payments (multipay) |
consumer_data | optional | Extended consumer data |
consumer_data income | optional | Consumer’s income |
auth_code | optional | Consumer’s pin code |
checksum | required | Checksum |
Generating the checksum
base64 ( sha256 ( secret + order.total_amount + merchant_data.store + merchant_data.customer_age + merchant_data.last_order + merchant_data.last_order_amount + merchant_data.known_address + merchant_data.ltv ) )
Possible status codes
StatusCodes | Meaning |
---|---|
authorize_success | The payment was approved |
authorize_fail | The payment was rejected |
require_data | Check the message to see what is required |
authenticate_consumer |
Update
Example:
curl "https://api.paidy.com/pay/update" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer NTNlYAY0MDFjYTAxMyBlNDAzNDk2ZDE3" \
-d '{ \
"payment_id": "542e6dc61200008a077a4de3", \
"order": { \
"items": [{ \
"item_id": "1", \
"title": "アディダススニーカー", \
"amount": 1000, \
"quantity": 1 \
},{ \
"item_id": "2", \
"title": "ナイキスニーカー", \
"amount": 1500, \
"quantity": 1 \
}], \
"tax": 300, \
"shipping": 500, \
"total_amount": 4800 \
},
"checksum": "2P0GS+O1W49HP4IQA3uhjb2Q/ans+zEEYHjT3YCJHho=" \
}'
The above command sends a JSON like below:
{
"payment_id": "542e6dc61200008a077a4de3",
"order": {
"items": [{
"item_id": "1",
"title": "アディダススニーカー",
"amount": 1000,
"quantity": 1
},{
"item_id": "2",
"title": "ナイキスニーカー",
"amount": 1500,
"quantity": 1
}],
"tax": 300,
"shipping": 500,
"total_amount": 4800
},
"checksum": "2P0GS+O1W49HP4IQA3uhjb2Q/ans+zEEYHjT3YCJHho="
}
The above command returns JSON structured like this:
{
"payment_id":"542e6dc61200008a077a4de3",
"status":"update_success"
}
Updating an existing Payment’s order
Change the Order object in the Payment.
HTTP Request
POST https://api.paidy.com/pay/update
Query Parameters
Parameter | Required | Description |
---|---|---|
payment_id | required | The Payment ID |
order | required | Purchase data including the items, quantity and amounts |
order items | required | Order/Cart/Basket data |
order items item item_id | optional | Defaults to a sequence integer |
order items item title | required | Description of the product |
order items item amount | required | Single item price |
order items item quantity | required | Quantity of this product |
order tax | optional | Tax amount for this order |
order shipping | optional | Shipping cost for this order |
order total_amount | required | Total payment amount |
checksum | required | Checksum |
Generating checksum
base64 ( sha256 ( secret + payment_id ) )
Possible status codes:
StatusCodes | Meaning |
---|---|
update_success | The payment was updated |
update_fail | The update failed |
Close
Example:
curl "https://api.paidy.com/pay/close" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer NTNlYAY0MDFjYTAxMyBlNDAzNDk2ZDE3" \
-d '{ \
"payment_id": "542e6dc61200008a077a4de3", \
"checksum": "2P0GS+O1W49HP4IQA3uhjb2Q/ans+zEEYHjT3YCJHho=" \
}'
The above command sends a JSON like below:
{
"payment_id": "542e6dc61200008a077a4de3",
"checksum": "2P0GS+O1W49HP4IQA3uhjb2Q/ans+zEEYHjT3YCJHho="
}
The above command returns JSON structured like this:
{
"payment_id":"542e6dc61200008a077a4de3",
"status":"close_success"
}
Close an existing payment
Close an open Payment. Useful when you are reaching the limited number of open Payments.
HTTP Request
POST https://api.paidy.com/pay/close
Query Parameters
Parameter | Required | Description |
---|---|---|
payment_id | required | The Payment ID |
checksum | required | Checksum |
Generating checksum
base64 ( sha256 ( secret + payment_id ) )
Possible status codes
StatusCodes | Meaning |
---|---|
close_success | The payment was closed |
close_fail | The payment was not closed (usually due to already expired or closed) |
Capture
Example:
curl "https://api.paidy.com/pay/capture" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer NTNlYAY0MDFjYTAxMyBlNDAzNDk2ZDE3" \
-d '{ \
"payment_id": "542e6dc61200008a077a4de3", \
"checksum": "2P0GS+O1W49HP4IQA3uhjb2Q/ans+zEEYHjT3YCJHho=" \
}'
The above command sends a JSON like below:
{
"payment_id": "542e6dc61200008a077a4de3",
"checksum": "2P0GS+O1W49HP4IQA3uhjb2Q/ans+zEEYHjT3YCJHho="
}
The above command returns JSON structured like this:
{
"payment_id":"542e6dc61200008a077a4de3",
"capture_id":"54ab90ba2500009700855852",
"status":"capture_success"
}
Capture an existing payment
Capture all of part of an open Payment
HTTP Request
POST https://api.paidy.com/pay/capture
Query Parameters
Parameter | Required | Description |
---|---|---|
payment_id | required | The Payment ID |
items item_id | optional | Defaults to a sequence integer |
items quantity | optional | Quantity of this product |
tax | optional | Tax amount for this order |
shipping | optional | Shipping cost for this order |
checksum | required | Checksum |
Generating checksum
base64 ( sha256 ( secret + payment_id ) )
Possible capture codes
StatusCodes | Meaning |
---|---|
capture_success | The payment was captured |
capture_fail | The capture request has been rejected |
Status
Example:
curl "https://api.paidy.com/pay/status" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer NTNlYAY0MDFjYTAxMyBlNDAzNDk2ZDE3" \
-d '{ \
"payment_id": "542e6dc61200008a077a4de3", \
"checksum": "2P0GS+O1W49HP4IQA3uhjb2Q/ans+zEEYHjT3YCJHho=" \
}'
The above command sends a JSON like below:
{
"payment_id": "542e6dc61200008a077a4de3",
"checksum": "2P0GS+O1W49HP4IQA3uhjb2Q/ans+zEEYHjT3YCJHho="
}
The above command returns JSON structured like this:
{
"payment_id":"542e6dc61200008a077a4de3",
"status":"open",
"test":false
}
Get the status of a payment
Get the current status of a Payment.
HTTP Request
POST https://api.paidy.com/pay/status
Query Parameters
Parameter | Required | Description |
---|---|---|
payment_id | required | The Payment ID |
checksum | required | Checksum |
Generating checksum
base64 ( sha256 ( secret + payment_id ) )
Possible status codes
StatusCodes | Meaning |
---|---|
open | The payment is open |
close | The payment is closed |
Refund
Example:
curl "https://api.paidy.com/pay/refund" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer NTNlYAY0MDFjYTAxMyBlNDAzNDk2ZDE3" \
-d '{ \
"capture_id":"54ab90ba2500009700855852", \
"checksum": "2P0GS+O1W49HP4IQA3uhjb2Q/ans+zEEYHjT3YCJHho=" \
}'
The above command sends a JSON like below:
{
"capture_id":"54ab90ba2500009700855852",
"checksum": "2P0GS+O1W49HP4IQA3uhjb2Q/ans+zEEYHjT3YCJHho="
}
The above command returns JSON structured like this:
{
"capture_id":"54ab90ba2500009700855852",
"status":"refund_success"
}
Refund a Payment
Refund all or part of a Payment’s value.
HTTP Request
POST https://api.paidy.com/pay/refund
Query Parameters
Parameter | Required | Description |
---|---|---|
capture_id | required | The Capture ID |
amount | optional | The amount to refund. If not set the total amount is refunded |
checksum | required | Checksum |
Generating checksum
base64 ( sha256 ( secret + capture_id ) )
Possible status codes
StatusCodes | Meaning |
---|---|
refund_success | The payment was refunded |
refund_fail | The refund request has been rejected |
Paidy Checkout
Paidy Checkout provides you with an easy-to-integrate payment method that works across all desktop browsers and mobile devices without any break in your existing payment flow. The Paidy Checkout, an embeddable javascript, handles the payment interface from within your site without the consumer leaving your checkout page. There’s no need to handle back button clicks, restoring cart data from the browser session or worrying about data formatting.
The Paidy Checkout takes care of creating the Authorization, which is then passed back to your page where you can submit it to your server along with any other customer details. Then within your server code you can capture the payment securely.
Checkout Demo
Try the demo below.
Implement Paidy Checkout
Example:
<script type="text/javascript" src="https://apps.paidy.com"></script>
<button id="atuh-btn">Authorize</button>
<script type="text/javascript">
var paidy = Paidy.configure({
key: "NTNlYAY0MDFjYTAxMyBlNDAzNDk2ZDE3",
callback: function(data){
$("#paidy_paymentid").val(data.payment_id);
$("#payment_form").submit();
}
});
$("#auth-btn").click ( function () {
var data = {
"buyer": {
"name": "山田 太郎",
"name2": "ヤマダ タロウ",
"dob": "1988-01-15",
"email": {
"address": "taro.yamada@paidy.com"
},
"address": {
"address1": "3-16-26",
"address2": "六本木",
"address3": "港区",
"address4": "東京都",
"postal_code": "106-0032"
},
"phone": {
"number": "03-4453-3234"
}
},
"order": {
"items": [{
"item_id": "1",
"title": "アディダススニーカー",
"amount": 1000,
"quantity": 1
},{
"item_id": "2",
"title": "ナイキスニーカー",
"amount": 1500,
"quantity": 1
}],
"tax": 300,
"shipping": 500,
"total_amount": 4800
},
"merchant_data": {
"store": "Test Store",
"customer_age": 2,
"last_order": 215,
"last_order_amount": 3500,
"known_address": false,
"ltv": 100
},
"checksum": "2P0GS+O1W49HP4IQA3uhjb2Q/ans+zEEYHjT3YCJHho=",
"test": true,
"tracking": {
"consumer_ip": "0.0.0.0"
}
};
paidy.launch(data);
return false;
});
</script>
When your page loads you should create a Paidy object that can be used to launch the Paidy Checkout. You can launch the Paidy Checkout in response to any event, such as clicking a button.
In the example you are binding to the click event of the pay-btn element. If this button is already used to submit an html form you can return false to prevent it submitting until after the Paidy Checkout has closed. In the callback you can submit the form, along with the payment_id. The required data to pass to the Paidy Checkout can be pregenerated by your server or you can use javascript to get the values from the page.
Webhook
Webhooks allow you to receive event information directly from Paidy’s servers to your own. Webhooks provide an alternate method of receiving Result objects to events such as authorization, captures and refunds. Instead of processing responses from your Paidy HTTP API requests or the Paidy Checkout, you process events sent to a URL you configure.
Integrate Webhook
You can configure your webhook URL when you log in to your account.
Request Body
An example of an authorize_success:
{
"payment_id":"542e6dc61200008a077a4de3",
"status":"authorize_success",
"event_type": "payment",
"order_ref":"abc123",
"event_datetime":"2015-01-29 18:28:37"
}
An example of an capture_success:
{
"payment_id":"542e6dc61200008a077a4de3",
"status":"capture_success",
"event_type": "payment",
"capture_id":"54ab90ba2500009700855852",
"event_datetime":"2015-01-29 18:28:37"
}
An example of an refund_success:
{
"capture_id":"54ab90ba2500009700855852",
"status":"refund_success",
"event_type": "payment",
"event_datetime":"2015-01-29 18:28:37"
}
Paidy’s servers make a HTTP POST request to a URL you configure in your account. The body of the request is the same JSON Result format as you would normally get from reading the HTTP response in API requests. We also include additional fields, such as your original order_ref so that you can match the event to an original order in your own system.
Request Body Parameters
Parameter | Description |
---|---|
payment_id | The Payment ID |
capture_id | The Capture ID |
status | (Refer to status codes blow) |
event_type | Type of Event |
order_ref | Merchant’s own reference |
event_datetime | event created date |
Possible status codes
StatusCodes | Meaning |
---|---|
authorize_success | The payment was approved |
capture_success | The payment was captured |
refund_success | The payment was refunded |