Cards: pre-authorization and capture
Pre-authorization lets you place a hold on funds on the customer's card without charging it immediately, and then capture all or part of the amount at a chosen time. You can cancel the unused hold. This is the standard model when the final amount or charge time is not known at the time of purchase.
POST/api/v1_0/cards/payment/{transactionId}/pay/card-pre-authPlace a hold on card funds without charging the card, with 3D Secure support.Full contract in the API Reference
POST/api/v1_0/cards/payment/{transactionId}/captureCapture all or part of the held funds.Full contract in the API Reference
POST/api/v1_0/cards/payment/{transactionId}/cancellationRelease the unused funds hold.Full contract in the API Reference
When to use it
- Reservations such as hotels and rentals: place a deposit hold and charge after the stay
- Charge on dispatch: charge only when the goods are ready to ship
- Variable amount: authorize with a margin and capture the final amount
- Marketplace: authorize now and settle after seller confirmation
You can also pre-authorize a saved token (card on file) by using the authorize_only field with
a recurring mandate alias; see Cards: recurring payments. This page describes
pre-authorization for a new card. Capture and cancellation work the same way for both variants.
How it works
The process has two phases:
- Pre-authorization places a hold on card funds without charging the card. The customer completes 3D Secure just as for a standard card payment.
- Capture OR cancellation either charges all or part of the held funds or releases the hold.
Pre-authorization uses the same card-data encryption and 3D Secure handling as Server-to-Server card payments. Read that guide first; this page describes only the differences.
Requirements
- An active Server-to-Server card integration, which requires PCI DSS certification and dpay approval; see Cards S2S
- Pre-authorization enabled for your Payment Point; contact dpay to enable it
Step 1: Register and pre-authorize the transaction
Register a transaction with transactionType: card_auth, retrieve the public key, and encrypt the
card data exactly as described in Cards S2S, steps 1–3. Only the payment endpoint
changes: use /pay/card-pre-auth instead of /pay/card-otp:
POST https://api-payments.dpay.pl/api/v1_0/cards/payment/{transactionId}/pay/card-pre-auth
Content-Type: application/json
Request parameters
They are identical to the parameters for /pay/card-otp:
{
"encryptedCardData": "Base64-encoded-encrypted-data...",
"deviceInfo": {
"browserAcceptHeader": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"browserJavaEnabled": "false",
"browserLanguage": "pl-PL",
"browserColorDepth": "24",
"browserScreenHeight": "1080",
"browserScreenWidth": "1920",
"browserTZ": "-60",
"browserUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)...",
"systemFamily": "Windows",
"geoLocalization": "52.2297,21.0122",
"deviceID": "device-unique-id",
"applicationName": "Chrome"
}
}
The deviceInfo object requires every field, including systemFamily, geoLocalization,
deviceID, and applicationName. Omitting any of them returns HTTP 422. See
Cards S2S for the complete specification.
Response
The response has the same structure as /pay/card-otp. The message.redirectType field
determines the next action:
redirectType | Meaning |
|---|---|
SUCCESS | Funds held successfully; proceed to capture or cancellation |
FORM | 3D Secure authentication required; render the form and retry with threeDsConfirmed: true |
Handle 3D Secure (FORM) exactly as described in Cards S2S. After successful
authorization, the funds are held but have not yet been charged. The value from transaction
registration is the maximum amount you can capture.
The issuing bank releases the funds hold after a certain period—usually several days to around two weeks, depending on the bank. Perform capture or cancellation before the hold expires.
Step 2a: Capture
Call the capture endpoint to charge the held funds. You can capture all or part of the authorization and perform multiple captures up to the authorized amount.
POST https://api-payments.dpay.pl/api/v1_0/cards/payment/{transactionId}/capture
Content-Type: application/json
Request parameters
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | Yes | Amount to capture in PLN, for example 59.99; the sum of all captures cannot exceed the authorized amount |
Example
curl -X POST https://api-payments.dpay.pl/api/v1_0/cards/payment/abc-def-123/capture \
-H "Content-Type: application/json" \
-d '{ "amount": 59.99 }'
Response
{
"success": true,
"status": "success",
"message": { "redirectType": "SUCCESS" }
}
When the total captured amount reaches the full authorization amount, the transaction moves to the captured state. You also receive the result of every capture through IPN.
If the final amount is lower than the authorized amount—for example, because part of the order is unavailable—capture only the actual amount. You can capture the remainder with another call or cancel it as described below.
Step 2b: Cancel the authorization
Call the cancellation endpoint to release held funds without charging them. Cancellation is available only while the authorization has not been fully captured.
POST https://api-payments.dpay.pl/api/v1_0/cards/payment/{transactionId}/cancellation
Content-Type: application/json
Request parameters
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | No | Amount to cancel in PLN. Omit it for full cancellation of the entire remaining uncaptured amount; provide it for partial cancellation |
Examples
Full cancellation, releasing the entire hold:
curl -X POST https://api-payments.dpay.pl/api/v1_0/cards/payment/abc-def-123/cancellation \
-H "Content-Type: application/json" \
-d '{}'
Partial cancellation, releasing part of the hold:
curl -X POST https://api-payments.dpay.pl/api/v1_0/cards/payment/abc-def-123/cancellation \
-H "Content-Type: application/json" \
-d '{ "amount": 30.00 }'
Response
{
"success": true,
"status": "success",
"message": { "redirectType": "SUCCESS" }
}
Full cancellation closes the authorization. Further capture or cancellation calls are no longer possible.
Lifecycle and constraints
| Rule | Description |
|---|---|
Capture requires amount | A capture amount is required; the total captured amount must not exceed the authorization amount |
Cancellation amount is optional | No amount means full cancellation of the remaining amount |
| Order of operations | You can cancel only an active authorization, not one that has been fully captured, canceled, or finalized |
| Captured amount | It cannot be canceled; only the uncaptured remainder can be canceled |
| Expiration | The issuing bank releases an uncaptured hold when it expires |
Error handling
| Message | Cause | Action |
|---|---|---|
Invalid capture amount | Missing or invalid capture amount | Provide a positive amount |
Capture amount exceeds authorized amount | Total captures exceed the authorization | Reduce the amount |
Transaction cannot be captured in its current state. | Authorization already captured, canceled, or finalized | Check the transaction status |
Transaction cannot be cancelled in its current state. | Authorization already captured, canceled, or finalized | Check the transaction status |
Cancellation amount exceeds remaining authorized amount | Cancellation amount exceeds the remaining hold | Reduce the amount |
Missing authorization reference for capture. / ... for cancellation. | The transaction has no authorization reference and is not an active pre-authorization | Verify that the transaction is a valid, unsettled pre-authorization |
Capture was declined by the card issuer. / Cancellation was declined by the card issuer. | The issuer declined the capture or cancellation | Check the transaction state and retry if appropriate |
Other processing errors, such as a declined authorization or invalid card, are described in the
shared Cards S2S guide. The message value can vary by situation, so avoid matching
it too strictly.
Testing in sandbox mode
For a service with test mode enabled, dpay simulates the entire pre-authorization flow without contacting an external card processor. You can test the full pre-authorization → capture or cancellation path using the test card numbers.
| Step | Test-mode behavior |
|---|---|
card-pre-auth with a success card number | Authorization succeeds and the transaction waits for capture |
card-pre-auth with a decline card number | Authorization is declined, the transaction is canceled, and a simulated error is returned |
capture | The funds capture is simulated; after full capture, the transaction receives the captured status |
cancellation | Cancellation is simulated; the pre-authorization is closed with the canceled status |
The authorization scenario—success or decline—is selected from the card number contained in the
encrypted card data, just as for card-otp payments. Test numbers are listed in
Test environment.