Delayed Capture
If you would like to allow your users to authorize a payment in their carts that you’ve created in the Cart Handoff Process, but need to capture the payment at a later time, using Delayed Capture with our Embedded Checkout may be the right solution for you.
When to Use Delayed Capture
- Your office needs to manually process a request or complete a business process before collecting payment for a user’s item and/ or
- You want your application to have control over when funds are captured after a user authorizes a payment in the Checkout Widget
Step 1: Create an Online Authorization-only Cart Handoff Request
When you are ready to hand this cart off to PaymentExpress, you will make a request to our Online Cart API to create the cart where the user will authorize their payment in our system. The request is a POST request similar to the below. Note the POST URL differs from the URL used for immediate capture carts.
POST /api/v1/pay/carts/authorizations
{
"request": {
"clientUserId": "Unique User ABCD",
"clientTransactionId": "F4BEF9CACEECE59",
"location": "<<defaultOnlineLocation>>",
"meta": {
"extra information": "here"
}
},
"items": [
{
"clientItemId": "1029347859728",
"description": "Property Taxes for Account #2890345",
"amount": "1257.38",
"type": "<<defaultOnlineItemType>>",
"fundCategory": "<<defaultOnlineFundCategory>>",
"meta": {
"extendedDescription": "value",
"extra reporting info": "here"
}
}
],
}The above request would create an authorize-only cart in our PaymentExpress payment portal with one item. Upon completing the process, you will have a response that looks something like this:
{
"cartId": "4ed4137c-3d89-44ad-92a1-c9f3e916f51e",
"checkoutURL": "https://govhub.com/<<govhubClient>>/<<defaultOnlineLocation>>/redirect/4ed4137c-3d89-44ad-92a1-c9f3e916f51e"
}You can ignore the checkoutURL value in this response, as that is used for Hosted Checkout. However, you will want to use the cartId value to load the Checkout Widget as outlined in our Embedded Checkout documentation.
Step 2: Create an HTML Element and Load the Checkout Widget
Once you have this cartId, you can easily instantiate the checkout widget right in your application, by calling the following JavaScript:
// The first parameter is an HTML selector for the element where you want to
// render the Checkout widget on your site.
CheckoutWidget.attach('#gsg-checkout', {
// Your site's identifier. This is the "location" value
// you specified in the cart request.
site: '{user.defaultOnlineLocation}',
// Use 'demo' in your non-production environment to make test payments.
// Use 'prod' in your production environment to make real payments.
environment: 'demo',
// The cart ID returned from the PaymentExpress Cart API:
cartId: '{{ cartId }}',
// We support 'en' and 'es':
language: 'en',
// This is called when the authorization is completed:
onSuccess: function (payload) {
// You can interact with the auth response here.
showAlert('Payment complete ' + JSON.stringify(payload))
},
// If you pass this handler, a "Cancel" button will be shown at the bottom of
// the shopping cart view. When clicked, this function will be called.
onCancel: function () {
showAlert('Payment canceled')
},
// This is called if there is an error loading the widget or submitting the
// authorization. The widget will also display the error, but you may also wish to
// record it in your own system.
onError: function (error) {
showAlert(error.message)
},
})An example of the expected response for the payload upon successful authorization is below:
{
"cartId": "0fbd77c4-8a10-4d51-b110-7b40025e3683",
"authorizationId": "5666DB3C-99F0-F2F0-1BCE-FC7BA53FBB7B",
"amounts": {
"primary": "163.00",
"fees": "4.08",
"total": "167.08"
}
}Your application should display any post-authorization message you want your users to review, and you should store this authorizationId with the cartId because it will be used to create the capture request. The authorizationId is only valid for up to 65 days. If it expires before you capture the payment, you will need to create a new authorization-only cart handoff request and have the user complete their authorization again.
Step 3: Create the Capture Request
When you want to charge the user’s authorized payment method, you will make a capture request to our Online Cart API using the cartId and authorizationId. The request is a POST request that includes the payment amounts to capture in the body. PaymentExpress validates the amounts passed in the request to ensure they match the amounts presented to user at authorization time.
POST /api/v1/pay/carts/authorizations/{cartId}/captures/{authorizationId}
{
"amounts": {
"primary": "1257.38",
"fees": "37.22",
"total": "1294.60"
}
}For a successful capture request, an example of the expected response is below. You should create or update the transaction record using the returned paymentId, mark all relevant items as paid in the system of record, and store the paymentId value for reconciliation.
{
"amounts": {
"primary": "1257.38",
"fees": "37.22",
"total": "1294.60"
},
"timestamp": "2026-04-01T14:10:47.016Z",
"paymentId": "J8350642623"
}On decline or failure, no payment is created and the response will not include a paymentId value. Your system of record should not mark items as paid. An example of a decline response is below.
{
"displayMessage": "Card declined - insufficient funds. Please try again with a different card. Contact the card issuer for more information.",
"errorCode": "PaymentDeclined",
"errorMessage": "Payment declined"
}The capture is initiated once the user is no longer interacting with our Checkout Widget, so your application must communicate the success or failure of the capture to the user. PaymentExpress will still send standard email or text receipts to the customer if those receipt notifications are enabled.
Updated about 15 hours ago