Bizum
Your account needs to enabled for this feature
Only supported for a specific acquirer in Spain.
Bizum is an asynchronous, redirect-based payment method for eCommerce transactions in Spain. The customer completes the payment on the Bizum-hosted page, and the merchant then retrieves the final transaction result from the Payments API.
This guide covers:
- creating a Bizum sale;
- redirecting the customer to Bizum;
- retrieving the final payment result;
- optionally separating customer authentication from a later sale authorization;
- submitting full or partial returns; and
- optionally creating and using a reusable Bizum payment token for merchant-initiated transactions.
Payment flow
- Submits an
ApmSaleTransactionwithpaymentMethod.typeset toBIZUM. - The API returns a transaction in
WAITINGstatus and supplies redirection instructions inrequiredActions.requiredRedirectionData. - Redirect the customer's browser using the returned
method,target, and any returnedparameters. - The customer authenticates and confirms the payment on the Bizum-hosted page.
- Bizum returns the customer's browser to the success URL supplied in the sale request.
- Retrieve the final transaction status by using the inquiry endpoint
Important: The browser return and the HTTP
200response from the initial sale request do not confirm that payment was approved. Fulfil the order only after a transaction inquiry returnstransactionResult=APPROVEDandtransactionState=CAPTURED.
Create a Bizum sale
Send a POST request to:
{baseUrl}/payments
Request fields
Presence: m = mandatory, c = conditional, o = optional.
| JSON path | Description | Presence |
|---|---|---|
requestType | Set to ApmSaleTransaction. | m |
transactionAmount.total | Payment amount. It must be greater than zero. | m |
transactionAmount.currency | Set to EUR. Bizum does not accept another transaction currency. | m |
paymentMethod.type | Set to BIZUM. | m |
storeId | Store identifier. Supply it when the API application can access more than one store. | c |
order.orderId | Merchant order identifier. If omitted, the Gateway generates one. Supplying your own unique value is recommended for reconciliation. | o |
transactionOrigin | Set to ECOM for an eCommerce payment. | o |
integrationData[].item=RETURN_URL | URL to which the customer's browser is returned after a successful flow. | m |
order.billing | Optional billing information used according to your risk and reporting setup. | o |
order.shipping | Optional shipping information used according to your risk and reporting setup. | o |
order.additionalDetails.scaExemptionType | Optional exemption request, when agreed for your integration. Supported examples include Low Value Exemption and TRA Exemption. | o |
Do not send card details or the customer's Bizum mobile number in the request. The customer supplies the mobile number on the Bizum-hosted page.
Example request
{
"requestType": "ApmSaleTransaction",
"transactionAmount": {
"total": 11.25,
"currency": "EUR"
},
"paymentMethod": {
"type": "BIZUM"
},
"storeId": "{{storeId}}",
"order": {
"orderId": "ORDER-10001"
},
"transactionOrigin": "ECOM",
"integrationData": [
{
"item": "RETURN_URL",
"value": "https://merchant.example/payments/bizum/success"
}
]
}
Example call:
curl --request POST \
--url ".../payments" \
--header "Content-Type: application/json" \
--header "Api-Key: ${API_KEY}" \
--header "Client-Request-Id: ${CLIENT_REQUEST_ID}" \
--header "Timestamp: ${TIMESTAMP}" \
--header "Message-Signature: ${MESSAGE_SIGNATURE}" \
--data @bizum-sale.json
Initial response
A successfully created Bizum payment normally returns HTTP 200 with a pending transaction and redirection data:
{
"ipgTransactionId": "838916029301",
"orderId": "ORDER-10001",
"transactionResult": "WAITING",
"transactionStatus": "WAITING",
"requiredActions": {
"requiredRedirectionData": {
"target": "https://bizum.example/payment/session",
"method": "GET"
}
}
}
Store ipgTransactionId and orderId. Use the redirection information exactly as returned:
- for
method=GET, navigate the customer's browser totarget; - for
method=POST, submit the returnedparameterstotarget; and - do not construct, modify, or reuse an old redirection URL.
transactionStatus is retained for compatibility but is deprecated. Use transactionResult for new integrations.
Retrieve the final result
After the customer returns to your site, retrieve the transaction on your server:
GET .../payments/{ipgTransactionId}?storeId={storeId}
Use the same authentication headers as for the sale request, with a new Client-Request-Id, timestamp, and signature.
Example approved result:
{
"ipgTransactionId": "838916029301",
"orderId": "ORDER-10001",
"transactionResult": "APPROVED",
"transactionState": "CAPTURED",
"processor": {
"responseCode": "CJ00000",
"responseMessage": "Operation performed correctly."
}
}
Interpret the response as follows:
transactionResult | Meaning | Merchant action |
|---|---|---|
APPROVED | The payment operation succeeded. | Fulfil only when transactionState is CAPTURED. |
WAITING | The customer or Bizum flow has not reached a final result. | Keep the order pending and repeat the inquiry using a bounded retry policy. |
DECLINED | Bizum or the Gateway declined the payment. | Do not fulfil the order. Show a neutral failure message and allow a new payment attempt. |
FAILED | The payment could not be processed. | Do not fulfil the order. Log the identifiers and error details for investigation. |
Processor codes and messages provide additional information, but they can change or be localized. Base payment fulfilment on transactionResult and transactionState, not on the browser return URL or message text.
Optional: split authentication
Split authentication separates the customer's Bizum authentication from the financial authorization:
- The customer authenticates through Bizum now.
- Your server submits the sale authorization later, when the order is ready to be charged.
The authentication step does not capture funds. Do not fulfil the order until the later sale transaction returns transactionResult=APPROVED and transactionState=CAPTURED.
Availability: Split authentication must be enabled for your store and supported by your acquiring agreement. Confirm its availability and the permitted authorization window during onboarding. The supported Bizum flow allows the authorization to follow the authentication by up to 30 days.
Split-authentication flow
- Submit an
ApmPayerAuthTransactionto create the authentication transaction. - Store its
ipgTransactionIdand redirect the customer usingrequiredActions.requiredRedirectionData. - After the browser returns, retrieve the authentication transaction until it reaches a final state.
- Continue only when the authentication has
transactionResult=APPROVEDandtransactionState=AUTHORIZED. - Submit an
ApmSaleTransactionwith the authenticated transaction's ID inipgTransactionId. - Store the new sale transaction ID and fulfil only when that sale is
APPROVEDandCAPTURED.
Step 1: authenticate the customer
Send a POST request to:
{baseUrl}/payments
The request fields are the same as for a standard Bizum sale, except that requestType is ApmPayerAuthTransaction:
{
"requestType": "ApmPayerAuthTransaction",
"transactionAmount": {
"total": 11.25,
"currency": "EUR"
},
"paymentMethod": {
"type": "BIZUM"
},
"storeId": "{{storeId}}",
"order": {
"orderId": "ORDER-SPLIT-10001"
},
"transactionOrigin": "ECOM",
"integrationData": [
{
"item": "RETURN_URL",
"value": "https://merchant.example/payments/bizum/authentication-success"
}
]
}
If an SCA exemption is part of your acquiring agreement, you can also supply order.additionalDetails.scaExemptionType in this request. Otherwise, omit it.
The initial response is normally WAITING and contains the same redirection structure as a standard Bizum sale. Redirect the customer's browser using the returned data without modifying it:
{
"ipgTransactionId": "1234567890",
"orderId": "ORDER-SPLIT-10001",
"transactionResult": "WAITING",
"transactionState": "WAITING",
"requiredActions": {
"requiredRedirectionData": {
"target": "https://bizum.example/authentication/session",
"method": "GET"
}
}
}
Step 2: confirm the authentication result
After the customer returns, retrieve the payer-auth transaction using its ipgTransactionId:
GET .../payments/{payerAuthTransactionId}?storeId={storeId}
Proceed to authorization only when the inquiry reports:
{
"ipgTransactionId": "1234567890",
"orderId": "ORDER-SPLIT-10001",
"transactionResult": "APPROVED",
"transactionState": "AUTHORIZED"
}
An AUTHORIZED payer-auth transaction confirms the customer's authentication; it is not yet a captured payment. If the state is still WAITING, continue the bounded inquiry process. Do not submit the sale when authentication is DECLINED or FAILED.
Step 3: submit the sale authorization
Submit another POST request to {baseUrl}/payments. Set requestType to ApmSaleTransaction and place the payer-auth transaction ID in the top-level ipgTransactionId field:
{
"requestType": "ApmSaleTransaction",
"transactionAmount": {
"total": 11.25,
"currency": "EUR"
},
"paymentMethod": {
"type": "BIZUM"
},
"storeId": "{{storeId}}",
"ipgTransactionId": 1234567890,
"transactionOrigin": "ECOM"
}
Use a new Client-Request-Id, timestamp, and signature for this request. The storeId must identify the same store that created the payer-auth transaction. The example intentionally omits order.orderId: the Gateway obtains the original order from the referenced ipgTransactionId.
Use the amount and currency authenticated in step 1 unless your acquiring agreement explicitly permits another amount. No second customer redirect is expected because the Bizum authentication has already completed.
A successful authorization returns a new sale transaction:
{
"ipgTransactionId": "1234567891",
"orderId": "ORDER-SPLIT-10001",
"transactionResult": "APPROVED",
"transactionState": "CAPTURED"
}
Keep both transaction IDs for traceability. Use the new sale transaction ID, not the payer-auth transaction ID, for returns and sale-related support inquiries.
Split authentication and reusable Bizum payment tokens solve different use cases. Split authentication links one customer authentication to its later sale authorization. A reusable token supports subsequent merchant-initiated payments under the applicable customer agreement.
Return a Bizum payment
Bizum supports full and partial returns against a successfully captured sale. Send a POST request to the original transaction:
{baseUrl}/payments/{ipgTransactionId}?storeId={storeId}
Example return request
{
"requestType": "ReturnTransaction",
"transactionAmount": {
"total": 2.00,
"currency": "EUR"
}
}
For a full return, set transactionAmount.total to the remaining captured amount. For a partial return, send the amount to return. Multiple partial returns are allowed while the cumulative returned amount does not exceed the captured amount.
Example response:
{
"ipgTransactionId": "838916029302",
"orderId": "ORDER-10001",
"transactionResult": "APPROVED",
"transactionState": "CAPTURED",
"processor": {
"responseCode": "CJ00000",
"responseMessage": "Operacion realizada correctamente"
}
}
Return rules:
- use the same
EURcurrency as the original sale; - reference the original sale's
ipgTransactionIdin the path; - do not return more than the amount that remains available; and
- do not submit a return for a declined, failed, or otherwise unsuccessful sale.
Optional: reusable Bizum payment token
This flow is available only when reusable Bizum tokens and merchant-initiated transactions are enabled for your store and permitted by your customer agreement.
Availability: Token-based transactions must be enabled for your store and supported by your acquiring agreement. Confirm its availability and the permitted authorization window during onboarding.
Create a token during the initial customer-authorized sale
Add createToken to the normal Bizum sale request:
{
"requestType": "ApmSaleTransaction",
"transactionAmount": {
"total": 11.25,
"currency": "EUR"
},
"paymentMethod": {
"type": "BIZUM"
},
"createToken": {
"reusable": true
},
"storeId": "{{storeId}}",
"order": {
"orderId": "ORDER-10002"
},
"transactionOrigin": "ECOM",
"integrationData": [
{
"item": "RETURN_URL",
"value": "https://merchant.example/payments/bizum/success"
}
]
}
The customer completes the initial redirect flow. After the transaction is approved, retrieve the transaction by ipgTransactionId, or retrieve the order by orderId, and store the returned token value:
{
"paymentToken": {
"value": "{{bizumPaymentToken}}",
"reusable": true,
"brand": "BIZUM",
"type": "PAYMENT_CARD"
}
}
Submit a subsequent merchant-initiated sale
Supply the saved token in paymentMethod.paymentToken:
{
"requestType": "ApmSaleTransaction",
"transactionAmount": {
"total": 7.50,
"currency": "EUR"
},
"paymentMethod": {
"type": "BIZUM",
"paymentToken": "{{bizumPaymentToken}}"
},
"storeId": "{{storeId}}",
"order": {
"orderId": "ORDER-10003"
},
"transactionOrigin": "ECOM"
}
A valid token causes the transaction to be submitted directly without creating another customer redirection link. Always inspect the returned transactionResult and transactionState; do not assume that a token-based payment is approved.
Validation and error handling
| Condition | Typical API result |
|---|---|
transactionAmount.total is zero | HTTP 409, error 600013: Invalid transaction amount. |
Currency is not EUR | HTTP 409, error 100010: The request value currency was invalid. |
| A return references an unsuccessful transaction | HTTP 409, error 600012: Invalid reference. |
A split-auth sale is submitted while authentication is still WAITING | The authorization is rejected. Continue inquiry and retry only after the payer-auth transaction is AUTHORIZED. |
| A split-auth sale references another store's transaction | The reference is rejected. Use the same store for both steps. |
| The payer-auth transaction has failed, was declined, or has expired | Do not reuse it. Start a new payer-auth transaction. |
| The store is not enabled for Bizum | The request is rejected as an unsupported or invalid payment configuration. |
| Bizum declines the payment | The inquiry returns transactionResult=DECLINED; processor details contain the provider response code and message. |
Do not use a provider response message as a stable programmatic interface. Record the HTTP status, Client-Request-Id, apiTraceId when present, ipgTransactionId, error code, and processor response code for support investigations.
Updated about 6 hours ago