Delayed Charge Flow¶
Overview¶
2-step Charge (Delayed Charge Flow) enables holding funds on the customer’s card before confirming the final settlement. This type of flow can be used in any business scenario that requires holding of funds for a certain amount of time before finalizing the payment on either by accepting the payment or voiding.
At Payelata.com processing, “Delayed Charge Flow“ is used to execute a 2-step charge transaction.
The 2-step charge flow includes 2 steps:
-
Create Authorize Transaction (Hold)
-
Process Transaction (Capture / Void)
The second action can be either Capture or Void, depending on your settings set in Dashboard UI or API request.
Step 1: Create Authorize Transaction (Hold)¶
API: PRIVATE
Endpoint: /payment-invoices
Authentication: BasicAuth
Method: POST
Required fields:
reference_id
— the unique identifier of the operation on the merchant side; if you do not specify it, the system will return a 422 error code.service
— the service identifier, for example, payment_card_usd_hpp: find a full list of available services in the dashboard or through Private API request.currency
— the invoice currency.amount
— the invoice amount in the float format, for example:100.55
.flow
— specify the type of invoice. In order to initiate a 2-step charge, putdelayed_charge
value in that field.customer[reference_id]
— required attribute if you send thecustomer
object.
Additional fields:
test_mode
— sendtrue
for test transactions; it isfalse
by default.description
customer
— object contains the client’s basic data and any associated metadata.reference_id
— required attribute for thecustomer
object in the request.name
email
phone
individual_tax_id
date_of_birth
metadata
— for thecustomer
object.address
— object for the customer's address data.country
region
city
streat
full_address
post_code
metadata
— for the Invoice.return_url
— a common URL for user return after payment.return_urls
— the object with 3 different URLs for user return after payment based on payment status.success
fail
pending
pending — required attribute for thereturn_urls
object in the request.
callback_url
— URL to send Callbacks when the transaction status changes.geteway_options
— gateway modification options, for example, modifying the Checkout page (we need to specify the set and possible values for each account).expires
— date and time of the invoice expiry in Datetime format; the expiry limit is between 14 minutes and 2 days from the date of the invoice creation.delayed_action
— Indicates the operation that is to be executed after delay expiration (can be:capture
orvoid
).delayed_action_delay
— States the time in minutes when to execute a delayed action.-
allow_partially
— Indicates whether the invoice can be partially captured. If that parameter is not included then it will be false, meaning partial capture is disabled.Note!
delayed_action
anddelayed_action_delay
parameters should be included in the attributes → options object.
JSON
{
"data":{
"type":"payment-invoices",
"attributes":{
"reference_id":"",
"amount":100,
"currency":"UAH",
"service":"payment_card_uah_hpp",
"flow":"delayed_charge",
"options":{
"delayed_action": "capture",
"delayed_action_delay": 60,
"allow_partially":true
},
"test_mode":true
},
"test_mode":true,
"description":"Invoice Example",
"gateway_options":{
"cardgate":{
"tokenize":false
}
},
"customer":{
"reference_id":"1203515",
"email":"somename@domain.com",
"name":"John Wick",
"phone":"+380987654321",
"metadata":{
"key1":"value1",
"key2":"value2"
}
},
"metadata":{
"key":"value"
},
"return_url":"https://example.com",
"return_urls": {
"success":"https://example.com/1",
"pending":"https://example.com/2",
"fail":"https://example.com/3"
},
"callback_url":"https://example.com"
}
}
{
"data": {
"type": "payment-invoices",
"id": "cpi_IPEphq1XwInHNOpH",
"attributes": {
"status": "authorize_pending",
"resolution": "ok",
"moderation_required": false,
"amount": 100,
"payment_amount": 100,
"currency": "UAH",
"service_amount": 100,
"payment_service_amount": 100,
"exchange_rate": 1,
"service_currency": "UAH",
"reference_id": "5587a275-f393-4599-948e-0efe4249559c",
"test_mode": true,
"fee": 0,
"failed_fee": null,
"deposit": 100,
"processed": null,
"processed_amount": null,
"refunded_amount": null,
"refunded_fee": null,
"refunded": null,
"processed_fee": null,
"processed_failed_fee": null,
"processed_deposit": null,
"failed": null,
"metadata": {
"key": "value"
},
"flow_data": {
"action": "https://example.io/hpp/cgi_G0bsyhroZj802zQU",
"method": "GET",
"params": [],
"metadata": {
"sid": "cgi_rb8eMnIYaDoRA1Qn",
"token": "yJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzaWQiOiJjZ2lfcmI5ZU1uSVlhRG9SQTFRbiIsImV4cGlyZXMiOm51bGwsImV4cCI6MTc1MTUyMzk2NX0.kvcZpCGI7rgw1mqYcUfgO2UmsnisH4Pda_s3Vucl7-k"
}
},
"flow": "hpp",
"payment_flow": "delayed_charge",
"created": 1751463965,
"updated": 1751463966,
"payload": null,
"description": "Description example ",
"descriptor": "Descriptor example ",
"callback_url": "https://example.com",
"return_url": "https://example.com",
"return_urls": {
"fail": "https://example.com/3",
"pending": "https://example.com/2",
"success": "https://example.com/1"
},
"original_data": [],
"rrn": null,
"arn": null,
"approval_code": null,
"reserved_amount": null,
"reserve_expires": null,
"unreserved": null,
"source": "merchant_api",
"callback_logs": [],
"charged_back_amount": null,
"charged_back": null,
"resolution_message": null,
"hpp_url": "https://example.io/com/redirect/hpp/?cpi=cpi_IPEphq1XwInHNOpH",
"refunds": [],
"reserves": [],
"reserve_options": null,
"processed_unreserve": null,
"processed_reserve_cancel": null,
"reserve_cancelled": null,
"delayed_action": null,
"delayed_action_at": null
},
"relationships": {
"payment-service": {
"data": {
"type": "payment-services",
"id": "payment_card_uah_hpp"
}
},
"payment-method": {
"data": {
"type": "payment-methods",
"id": "payment_card"
}
},
"customer": {
"data": {
"type": "customers",
"id": "cus_F0zqT9wWKBeJ51DA"
}
}
},
"active-payment": {
"data": {
"type": "payments",
"id": "pay_Uvlm8WChE2OVeZ7Qu2FAk8q9"
}
}
},
"links": {
"self": "/api/payment-invoices/cpi_ADzwZTG99f3q3utQ"
}
}
}
Note!
The `flow` parameter is set to `charge` by default which is a simple charge flow with 1-step payment.
Note!
If you include a `delayed_action` parameter in your request, then `delayed_action_delay` parameter becomes required. Otherwise, you will receive a 422 error code response.
Note!
The `delayed_action_delay` parameter is to be set in minutes.
Note!
Providers' delayed action (capture/void) has priority over merchants' settings in invoice initiation settings. Make sure to align with your provider's settings regarding 2-step charges.
After the invoice has been initiated, it obtains the authorize_pending
status with a waiting_for second_step
resolution. At this point customer has to authorize the transaction by confirming the payment.
There are 2 ways to redirect the user to the payment page:
-
Use
flow_data
to build html form: form action =>action
, form method =>method
form hidden parameters =>params
(if present in the response). -
Use
hpp_url
: redirect user directly to provided URL (using GET method).
In case you're integrated via H2H flow, feel free to refer to Sending info to Gateway section for more information.
Step 2: Authorize payment¶
After the Customer has confirmed the payment with their card, Invoice obtains authorized status and will automatically be captured or voided according to options specified in the request or Dashboard UI.
Manual Capture Operation¶
API: PRIVATE
Authentication: BasicAuth
Endpoint: /payment-invoices/{id}/capture
Method: POST
Required fields:
id
— the unique identifier of the payment invoice.amount
— amount to be captured. Payment Invoice optionallow_partially
must be true to capture a partial amount [amount
].type
— type of transaction to be executed.
Note!
Payment Invoice option `allow_partially` must be true to capture a partial amount [`amount`].
JSON
{
"data": {
"id": "cpi_IPEphq1XwInHNOpH",
"type": "payment-invoices",
"attributes": {
"amount": "100"
}
}
{
"data": {
"type": "payment-invoices",
"id": "cpi_IREphq1XwInHNOpH",
"attributes": {
"status": "processed",
"resolution": "ok",
"moderation_required": false,
"amount": 100,
"payment_amount": 100,
"currency": "UAH",
"service_amount": 100,
"service_service_amount": 100,
"exchange_rate": 1,
"service_currency": "UAH",
"reference_id": "0787a275-f393-4599-948e-0efe4249559c",
"test_mode": true,
"fee": 0,
"failed_fee": null,
"deposit": 100,
"processed": 1751467114,
"processed_amount": 100,
"refunded_amount": null,
"refunded_fee": null,
"refunded": null,
"processed_fee": 0,
"processed_failed_fee": null,
"processed_deposit": 100,
"metadata": {
"key": "value"
},
"flow_data": {
"action": "https://example.io/hpp/cgi_rb9epnIYaDoRA1Qn",
"method": "GET",
"params": [],
"metadata": {
"sid": "cgi_rb9eMnIYaDoRA1Qn",
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9eyJzaWQiOiJjZ2lfcmI5ZU1uSVlhRG9SQTFRbiIsImV4cGlyZXMiOm51bGwsImV4cCI6MTc1MTUyMzk2NX0.kvcZpCGI7rgw1mqYcUfgO2UmsnisH4Pda_s3Vucl7-k"
}
},
"flow": "hpp",
"payment_flow": "delayed_charge",
"created": 1751463965,
"updated": 1751467114,
"payload": {
"token": null,
"auth_type": "card",
"client_ip": "",
"payment_card": {
"last": "0000",
"mask": "551928******0000",
"type": "debit",
"brand": "standard",
"first": "551928",
"holder": "Card Holder",
"card_id": "card_NhsVH7nuCDXwC6HN",
"network": "mastercard",
"expiry_year": "77",
"issuer_name": "U.S. BANK, N.A.",
"expiry_month": "06",
"reference_id": "ceeac179849e247ac69d0bbaf86ff7311793dbd06a160f242a3313d8c019b5e4",
"issuer_country": "US"
}
},
"description": "Descriptor Example",
"descriptor": "Descriptor Example",
"callback_url": "https://example.com",
"return_url": "https://example.com ",
"return_urls": {
"fail": "https://example.com/3",
"pending": "https://example.com/2",
"success": "https://example.com/1"
},
"original_data": {
"original_resolution_message": null
},
"rrn": 35836585,
"arn": 32100626,
"approval_code": null,
"reserved_amount": null,
"reserve_expires": null,
"unreserved": null,
"source": "merchant_api",
"callback_logs": [],
"charged_back_amount": null,
"charged_back": null,
"resolution_message": null,
"hpp_url": "https://example.io/redirect/hpp/?cpi=cpi_IPEphq1XwInHNOpH ",
"refunds": [],
"reserves": [],
"reserve_options": null,
"processed_unreserve": null,
"processed_reserve_cancel": null,
"reserve_cancelled": null,
"delayed_action": "capture",
"delayed_action_at": 1751469448
},
"relationships": {
"payment-service": {
"data": {
"type": "payment-services",
"id": "payment_card_uah_hpp"
}
},
"payment-method": {
"data": {
"type": "payment-methods",
"id": "payment_card"
}
},
"customer": {
"data": {
"type": "customers",
"id": "cus_F0zqT9wWKBeJ51DA"
}
}
},
"active-payment": {
"data": {
"type": "payments",
"id": "pay_Uvlm8WChE2OVeZ7Qu2FAk8q9"
}
}
},
"links": {
"self": "/api/payment-invoices/cpi_IPEphq1XwInHNOpH"
}
}
}
Manual Void Operation¶
API: PRIVATE
Authentication: BasicAuth
Endpoint: /payment-invoices/{id}/void
Method: POST
Required fields:
id
— the unique identifier of the payment invoice.amount
— amount to be captured.type
— type of transaction (for simplicity always specify as “payment-invoices“).
Note!
Only full settlement amount void is available.
JSON
{
"data": {
"id": "cpi_sfLwYheSIkggvXos",
"type": "payment-invoices",
"attributes": {
}
}
{
"data": {
"type": "payment-invoices",
"id": "cpi_sfLwYheSIkggvXos",
"attributes": {
"status": "voided",
"resolution": "ok",
"moderation_required": false,
"amount": 100,
"payment_amount": 100,
"currency": "UAH",
"service_amount": 100,
"service_service_amount": 100,
"exchange_rate": 1,
"service_currency": "UAH",
"reference_id": "819e148d-99ad-44b2-b4b0-27ced5bc1ea5",
"test_mode": true,
"fee": 0,
"failed_fee": null,
"deposit": 100,
"processed": 1751475289,
"processed_amount": null,
"refunded_amount": null,
"refunded_fee": null,
"refunded": null,
"processed_fee": null,
"processed_failed_fee": null,
"processed_deposit": null,
"metadata": {
"key": "value"
},
"flow_data": {
"action": "https://example.io/hpp/cgi_UGT4iyQxQKFLUBlq",
"method": "GET",
"params": [],
"metadata": {
"sid": "cgi_UGT4iyQxQKFLUBlq",
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzaWQiOiJjZ2lfVUdUNGl5UXhRS0ZMVUJscSIsImV4cGlyZXMiOm51bGwsImV4cCI6MTc1MTUzMjI1M30.VYWX-dfLdlO-vwoQdBtHElIsrTA-CZ9DzrzqE96f3QU"
}
},
"flow": "hpp",
"payment_flow": "delayed_charge",
"created": 1751472253,
"updated": 1751475289,
"payload": null,
"description": "Invoice Example",
"descriptor": null,
"callback_url": "https://example.com",
"return_url": "https://example.com ",
"return_urls": {
"fail": "https://example.com/3",
"pending": "https://example.com/2",
"success": "https://example.com/1"
},
"original_data": {
"original_resolution_message": null
},
"rrn": 43790482,
"arn": 93811109,
"approval_code": null,
"reserved_amount": null,
"reserve_expires": null,
"unreserved": null,
"source": "merchant_api",
"callback_logs": [],
"charged_back_amount": null,
"charged_back": null,
"resolution_message": null,
"hpp_url": "https://example.io/redirect/hpp/?cpi=cpi_sfLwYheSIkggvXos ",
"refunds": [],
"reserves": [],
"reserve_options": null,
"processed_unreserve": null,
"processed_reserve_cancel": null,
"reserve_cancelled": null,
"delayed_action": null,
"delayed_action_at": null
},
"relationships": {
"payment-service": {
"data": {
"type": "payment-services",
"id": "payment_card_uah_hpp"
}
},
"payment-method": {
"data": {
"type": "payment-methods",
"id": "payment_card"
}
},
"customer": {
"data": {
"type": "customers",
"id": "cus_F0zqT9wWKBeJ51DA"
}
}
},
"active-payment": {
"data": {
"type": "payments",
"id": "pay_sKO1dceiKjug8XUdb3g9WegN"
}
}
},
"links": {
"self": "/api/payment-invoices/cpi_sfLwYheSIkggvXos"
}
}
}
Delayed Charge flow unqie error codes
Code | Step | Explanation |
---|---|---|
422 | "This value should be greater than or equal to 60" | delayed_action_delay parameter is set to less then 60 at invoice initiation |
422 | “To use option delayed_action, option delay must be passed or set in Commerce Account payment options” | If you include a delayed_action parameter to your request, then the delayed_action_delay parameter becomes required. Because delayed action must have time. |
422 | “Options delay and delayed_action can be used only with flow delayed_charge“ | Parameters delayed_action and delayed_action_delay parameter becomes required. Because delayed action must have time. |