Bizum Redirect
Bizum is a widely adopted instant mobile payment solution in Spain, created through the collaboration of local banks. It allows customers to pay directly from their bank account using only a phone number, delivering instant confirmation without exposing card details. Unlike the backend-to-backend Bizum API Rest integration, this flow generates a redirect: the API response returns a signed URL and form parameters that your backend uses to send the customer to the Bizum payment gateway. The customer completes the payment there and is redirected back to your callback_url. The Global API supports Bizum Redirect in two flows:
- Single-step flow – authorize and capture the payment in one request using
INSTANT_TRANSFER. - Two-step flow – validate the customer’s Bizum account in one step using
INSTANT_TRANSFER_PREAUTH, then capture the payment later (within 30 days) when you are ready to fulfill the order.
Bizum does not support transaction cancellations in the two-step flow. An authorization does not “hold” funds, if the customer’s balance drops before you perform the Capture, the transaction will fail due to insufficient funds.
This guide consolidates the full instructions for both flows, including request examples, redirect handling, callback processing, and capture logic.
Requirements
Before integrating Bizum you need to:
- Generate an access token through the Authentication endpoint.
- Configure a public HTTPS
callback_urlthat receives status updates after customers leave the Bizum interface.
Bizum is only available in Spain (
EUR). Contact your Account Manager to enable this payment method for your seller account.Maximum amount: Bizum transactions are capped at €15,000. The customer’s bank can enforce a lower limit, so a transaction below €15,000 may still be refused.
Use Cases Specifics
When integrating any Getnet solution, market-specific requirements apply. Bizum is only available in Spain and only for EUR currency. To know more about the specific requirements of Spain, be sure to review the resources below before you go live:
You can also use test cards to simulate specific scenarios.
Testing Bizum Payments
When testing Bizum payments in the sandbox environment, use the following credentials and amounts to simulate different scenarios.
Test Phone Number
Use the following phone number for testing Bizum transactions in the sandbox environment:
Test Phone Number: 700 000 000
This phone number will allow you to complete the Bizum payment flow in the test environment without requiring an actual Bizum account.
Test Amounts
Different transaction amounts will simulate different payment outcomes in the sandbox environment. Use the table below to test various scenarios:
| Amount | Outcome | Description |
|---|---|---|
| Less than €5 | Payment confirmed | Transaction is successful and immediately approved |
| €5 to €10 | Payment confirmed | Transaction is successful with normal processing |
| €10 to €500 | Payment confirmed | Transaction is successful for standard amounts |
| More than €500 | Payment refused | Transaction is declined to simulate high-value rejections |
These test scenarios are only available in the sandbox environment. Production transactions will be processed normally based on the customer’s actual Bizum account status and balance.
Shared Characteristics
The table below summarizes the shared behavior and requirements for both Bizum payment flows.
| Capability | Details |
|---|---|
| Redirect experience | Customers are redirected to the Bizum gateway (HTML template or URL) |
| Credentials required | Customer’s Bizum-enabled phone number validated by their bank |
| Confirmation | Real-time response, followed by redirect + callback |
| Notifications | Register events via the Webhooks API to receive asynchronous status updates. See Webhooks for the available events |
All flows return three parameters in the additional_data object (merchant_data, signature_version, and signature) that you must use to build an HTML form for redirecting the customer to the Bizum gateway. The form POSTs to the URL provided in additional_data._links[0].href. Both flows also send Base64 encoded merchant_data that you should decode on your backend to reconcile the transaction.
Available Features
Use the matrix below to confirm the scenarios currently supported for Bizum.
| Payment flow | Supported countries | Purchases | Refunds | Partial refunds | Multiple refunds | Pre-authorizations |
|---|---|---|---|---|---|---|
| Redirect | Spain | ✅ | ✅ | ✅ | ✅ | ✅ |
To enable Bizum you must work with your Account Manager, who validates eligibility and activates the payment method.
Single-step Flow (Immediate Capture)
Use this flow when you can fulfill the order immediately. Funds move in the same request that creates the payment.
The diagram below provides an overview of the single-step flow:
1. Create the Payment Request
Call the Create – Authorize endpoint with the attributes below.
The table outlines the minimum fields required to create a Bizum single-step payment.
| Attribute | Description | Required value |
|---|---|---|
payment_method | Bizum single-step method | INSTANT_TRANSFER |
callback_url | Where Bizum redirects the customer after success/cancel | Your HTTPS endpoint |
amount | Transaction amount in cents. Maximum 1500000 (€15,000) | Integer (e.g. 5000 for €50.00) |
currency | ISO currency code | EUR |
order_id | Merchant reference for reconciliation | Unique string |
The following sample request shows how to initialize a Bizum single-step payment.
curl --request POST \
--url https://api-sbx.globalgetnet.com/dpm/payments-gwproxy/v2/payments \
--header 'authorization: Bearer <your-token>' \
--header 'content-type: application/json' \
--header 'x-seller-id: 54f88e68-7764-4e87-8830-756b1e2c02f8' \
--header 'x-transaction-channel-entry: XX' \
--data '{
"idempotency_key": "63c7f8ee-51a6-470d-bb76-ef762b62bfb9",
"request_id": "daac03dc-73db-453f-9bea-b1391669d5d3",
"order_id": "ORDER-10187383",
"data": {
"amount": 5000,
"currency": "EUR",
"customer_id": "customer-123",
"payment": {
"payment_method": "INSTANT_TRANSFER",
"transaction_type": "FULL"
},
"additional_data": {
"callback_url": "https://your-store.com/payment/callback"
}
}
}'The API responds with a payload containing three essential parameters in the additional_data object that you must use to build the redirect form:
| Parameter | Description | Maps to Form Field |
|---|---|---|
merchant_data | Base64-encoded merchant parameters | Ds_MerchantParameters |
signature_version | Signature version identifier | DS_SignatureVersion |
signature | Payment signature for validation | DS_Signature |
{
"idempotency_key": "be278973-35eb-4c45-8619-2800d62b33b6",
"seller_id": "2ab3e585-3607-467e-b2e8-420fcd45f48e",
"payment_id": "772f951479c6514b1d9c4e8fd4808fe6",
"order_id": "99155671997",
"amount": "400",
"currency": "EUR",
"status": "WAITING",
"received_at": "2025-11-11T11:51:54.569Z",
"reason_code": "00",
"reason_message": "Waiting payment flow.",
"additional_data": {
"_links": [
{
"href": "https://sis-i.redsys.es:25443/sis/realizarPago",
"rel": "apm_html",
"type": "POST"
}
],
"signature": "x2LEfpqXz_t2UaerHjZyLjcT67yDBiFE7BmmcwXlTkBX5RiTtdsKlZWHVSQRkklJNkB8nTRC7f46RjEfp92QA==",
"merchant_data": "eyJ1cmwiOiJodHRwczovL3N1cmwuaW8vcGVuL3V0aS9hcGkvbnRmVW5mVUSQo0hBTlRDSF10RDFoji0NDgwMDAxMTEiLCJEU19NRVDSOEFOFV9URU5fRUjl6jklc5MUTh1NjcxOTk3IiwiRENFTUVSODQhBTlTRFDUFNFTUVSOQhBTRIDORfTFIojNDgwMDAxMTEiLCJEU19NRVDSOEFOFV9URU5FSTBCI6IjE1LCJEU1V9NRVDSOEFOFV9UUkFOUFODVEIlPTRZEUOi0i3IiwiRENFTUVSODQhBTlTRFUQV9RU0hFTFQiOVSJkVOQ1lOiR5NIJGNzlCUE9IRVDSOEFOV9RRUJFOUQI0i0MDAiLCJEU19NRVDSOEFOFV9NRVDSOEFOBVRERUOiV0iJ7C/WyXtZlZw5OSWRCijdplcj3SMvN5TNlOeZNjJeJi1NDFiZDljNDU4ZmQ0ODA4ZmU2KC9JiwiRENFTUVSODQhBTlTRFUEZTUUVLVE5UE9Yl6lNOciJUE19NRVDSOEFOFV9NRVDSOEFOFV9RRUbTV5ClN6hj9w2IsBNc5R3l9GiwxNnZrRzUXc2UzQv92tL2Rwb952bWFydWE1Cl1bmIaWVkYXBpL3kxL3ByZWZyZWxlbnNlfQ==",
"signature_version": "T2SV2"
}
}2. Redirect the Customer
Extract the three parameters from the API response (merchant_data, signature_version, and signature) and use them to build an HTML form that POSTs to the Bizum payment gateway. The form must include these values as hidden input fields with the exact field names: Ds_MerchantParameters, DS_SignatureVersion, and DS_Signature.
The form should POST to the URL provided in additional_data._links[0].href from the API response. Important: Always use the URL from the API response, as it will differ between UAT (testing) and production environments. The URL shown in the example below (https://sis-i.redsys.es:25443/sis/realizarPago) is for the UAT environment only. See the Redirect template example for a complete implementation.
3. Handle the Callback
When the customer finishes, Bizum redirects to your callback_url with the payment status and Base64 merchant_data. The callback typically looks like the response below.
{
"idempotency_key": "10bba4d0-23ff-4950-ad6e-baa3f8590229",
"seller_id": "2ab3e585-3607-467e-b2e8-420fcd45f48e",
"payment_id": "777f851479c64541bd9c4e8fd4808fe9",
"order_id": "ORDER-10187383",
"amount": "5000",
"currency": "EUR",
"status": "WAITING",
"received_at": "2025-11-03T14:18:59.991Z",
"reason_code": "00",
"reason_message": "Waiting payment flow.",
"additional_data": {
"signature": "iTp-RJzON_lpCcO2A34RBgWbPj8GwBpKBlDYugx8xA...",
"_links": [
{
"rel": "apm_html",
"type": "POST",
"href": "https://sis-i.redsys.es:25443/sis/realizarPago"
}
],
"merchant_data": "eyJvcmRlcl9pZCI6Ik9SREVSLTEwMTg3MzgzIiwicGF5bWVudF9pZCI6Ijc3N2Y4NTE0NzljNjQ1NDFiZDljNGU4ZmQ0ODA4ZmU5IiwiYW1vdW50IjoiNTAwMCIsImN1cnJlbmN5IjoiRVVSIiwibWVyY2hhbnRfY29kZSI6IjQ4MDAwMTExIiwidHJhbnNhY3Rpb25fdHlwZSI6InBheW1lbnQifQ==",
"signature_version": "T25V2"
}
}Decode merchant_data on your backend (see Decoding merchant_data).
4. Verify Status (Optional)
For long-running transactions, periodically check the Get Transaction endpoint or rely on Webhooks for final confirmation.
Two-step Flow (Validation + Capture)
Bizum does not support transaction cancellations in the two-step flow. An authorization does not “hold” funds, if the customer’s balance drops before you perform the Capture, the transaction will fail due to insufficient funds.
Choose this flow when you need to validate the customer’s Bizum account first and capture the payment after fulfillment. This flow validates the account in one step and allows you to capture the payment within 30 days.
The diagram below provides an overview of the two-step flow:
1. Validate the Payment
Send the same endpoint request but set payment_method = INSTANT_TRANSFER_PREAUTH.
The next table lists the key attributes needed for the validation request.
| Attribute | Type | Required | Description |
|---|---|---|---|
idempotency_key | String (UUID) | Yes | Unique identifier to ensure the request is processed only once. Use a UUID v4 format. If you retry a request with the same key, the API returns the original result |
request_id | String (UUID) | Yes | Unique identifier for tracking the request. Use a UUID v4 format for better traceability across systems |
order_id | String | Yes | Your unique identifier for the purchase. This is the merchant’s reference ID used for reconciliation purposes |
data.amount | Integer | Yes | Transaction amount in cents (minor units). For example, 5000 represents €50.00. Must be a positive integer. Maximum 1500000 (€15,000) |
data.currency | String | Yes | ISO 4217 currency code. Must be EUR for Bizum payments as they are only available in Spain |
data.customer_id | String | No | Unique identifier for the customer in your system. Useful for tracking customer payment history |
data.payment.payment_method | String | Yes | Payment method identifier. Must be INSTANT_TRANSFER_PREAUTH for Bizum two-step (pre-authorization) payments |
data.payment.transaction_type | String | Yes | Transaction processing type. Must be FULL for Bizum as partial payments are not supported |
data.additional_data.callback_url | String (URL) | Yes | HTTPS endpoint where Bizum redirects the customer after they complete or cancel the payment. Must be publicly accessible and use HTTPS protocol |
Here is an example request that validates a Bizum payment.
curl --request POST \
--url https://api-sbx.globalgetnet.com/dpm/payments-gwproxy/v2/payments \
--header 'authorization: Bearer <your-token>' \
--header 'content-type: application/json' \
--header 'x-seller-id: 54f88e68-7764-4e87-8830-756b1e2c02f8' \
--header 'x-transaction-channel-entry: XX' \
--data '{
"idempotency_key": "63c7f8ee-51a6-470d-bb76-ef762b62bfb9",
"request_id": "daac03dc-73db-453f-9bea-b1391669d5d3",
"order_id": "ORDER-10187384",
"data": {
"amount": 5000,
"currency": "EUR",
"customer_id": "customer-123",
"payment": {
"payment_method": "INSTANT_TRANSFER_PREAUTH",
"transaction_type": "FULL"
},
"additional_data": {
"callback_url": "https://your-store.com/payment/callback"
}
}
}'The response mirrors the single-step example and includes the three required parameters (merchant_data, signature_version, and signature) in additional_data that you must use to build the redirect form.
2. Redirect the Customer
Extract the three parameters from the API response and build the HTML form as described in the Redirect template example. The customer approves the payment within Bizum, and you receive an AUTHORIZED status in the callback.
{
"idempotency_key": "10bba4d0-23ff-4950-ad6e-baa3f8590229",
"seller_id": "2ab3e585-3607-467e-b2e8-420fcd45f48e",
"payment_id": "777f851479c64541bd9c4e8fd4808fe9",
"order_id": "ORDER-10187384",
"amount": "5000",
"currency": "EUR",
"status": "AUTHORIZED",
"received_at": "2025-11-03T14:18:59.991Z",
"authorized_at": "2025-11-03T14:19:15.123Z",
"reason_code": "00",
"reason_message": "Authorization successful"
}3. Capture the Validated Payment
When you are ready to complete the sale, call the Capture endpoint. The payment_method must remain INSTANT_TRANSFER_PREAUTH. You can capture the payment within 30 days of validation. The request below captures the previously validated payment.
curl --request POST \
--url https://api-sbx.globalgetnet.com/dpm/payments-gwproxy/v2/payments/capture \
--header 'authorization: Bearer <your-token>' \
--header 'content-type: application/json' \
--data '{
"idempotency_key": "11c7f8ee-51a6-470d-bb76-ef762b62bfb1",
"payment_id": "777f851479c64541bd9c4e8fd4808fe9",
"payment_method": "INSTANT_TRANSFER_PREAUTH",
"amount": 5000
}'If the capture succeeds you receive a response like this:
{
"seller_id": "54f88e68-7764-4e87-8830-756b1e2c02f8",
"payment_id": "777f851479c64541bd9c4e8fd4808fe9",
"idempotency_key": "11c7f8ee-51a6-470d-bb76-ef762b62bfb1",
"order_id": "ORDER-10187384",
"amount": 5000,
"currency": "EUR",
"status": "CAPTURED",
"reason_code": "00",
"reason_message": "Captured successfully",
"captured_at": "2025-11-03T15:20:30.456Z"
}4. Confirm Settlement
Check the transaction status or rely on Webhooks to confirm the payment has transitioned from AUTHORIZED to CAPTURED.
Bizum-specific considerations:
- Payment method: Always specify the correct
payment_methodvalue (INSTANT_TRANSFERorINSTANT_TRANSFER_PREAUTH) that was used in the original transaction.
For detailed information about the refund process, full and partial refunds, timing considerations, and best practices, see the Refund a Payment guide.
Webhooks
To receive asynchronous status updates for Bizum Redirect transactions, register webhook events via the Webhooks API. Bizum webhook events work differently from card payment webhooks — you must register the specific events below to cover all transaction lifecycle transitions.
| Event | Description |
|---|---|
APPROVED_TRANSACTIONS | Triggered whenever a Payout is processed |
AUTHORIZED_TRANSACTIONS | Triggered whenever a transaction is authorized, in either the Single-step or Two-step flow |
CAPTURED_TRANSACTIONS | Triggered whenever a post-authorization capture occurs (Two-step flow) |
CANCELLED_TRANSACTIONS | Triggered when a cancellation is performed via the /cancel service |
PENDING_TRANSACTIONS | Triggered whenever a transaction is created and is awaiting payment confirmation in Bizum |
Redirect Template Example
After receiving the payment creation response, extract the three parameters from additional_data and build an HTML form that automatically submits to the Bizum payment gateway. The form must include the following hidden input fields with the exact names shown:
Ds_MerchantParameters— use the value fromadditional_data.merchant_dataDS_SignatureVersion— use the value fromadditional_data.signature_versionDS_Signature— use the value fromadditional_data.signature
The form should POST to the URL found in additional_data._links[0].href from the API response.
Always use the URL from the API response, as it will differ between testing and production environments. The URL shown in the example below (https://sis-t.redsys.es:25443/sis/realizarPago) is for the testing environment only. See the Redirect template example for a complete implementation.
Here is a complete HTML template that you can use:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Payment Redirect</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background-color: #f5f5f5;
}
.redirect-container {
text-align: center;
background: white;
padding: 40px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.spinner {
border: 4px solid #f3f3f3;
border-top: 4px solid #d50000;
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
h2 {
color: #333;
margin-bottom: 10px;
}
p {
color: #666;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="redirect-container">
<div class="spinner"></div>
<h2>Redirecting to Payment Gateway</h2>
<p>Please wait while we redirect you to complete your BIZUM payment...</p>
</div>
<form id="paymentForm" action="https://sis-i.redsys.es:25443/sis/realizarPago" method="POST" style="display: none;">
<!-- Hidden input fields required by the payment processor -->
<!-- Note: The action URL above is for UAT environment only. Use the URL from additional_data._links[0].href in production -->
<input type="hidden" name="Ds_Signature" value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX">
<input type="hidden" name="Ds_SignatureVersion" value="T25V2">
<input type="hidden" name="Ds_MerchantParameters" value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX">
</form>
<script>
// Automatically submit the form after the page loads
window.onload = function() {
// Add a small delay to show the loading screen briefly
setTimeout(function() {
const form = document.getElementById("paymentForm");
if (form && form.action && form.action !== "{{href}}") {
form.submit();
} else {
// If no valid action URL, show error
document.querySelector('.redirect-container').innerHTML =
'<h2 style="color: #d50000;">Error</h2>' +
'<p>Payment redirect URL not found. Please contact support.</p>';
}
}, 1500);
};
</script>
</body>
</html>Important: Replace the placeholder values in the form with the actual values from the API response:
- Replace
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXinDs_Signaturewith the value fromadditional_data.signature. - Replace
T25V2inDs_SignatureVersionwith the value fromadditional_data.signature_version. - Replace
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXinDs_MerchantParameterswith the value fromadditional_data.merchant_data. - Replace the
actionURL with the value fromadditional_data._links[0].href.
After the form is automatically submitted, the buyer will be redirected to the Bizum checkout page where they can complete the payment. The checkout page looks similar to this:
Decoding merchant_data
The following Node.js example demonstrates how to retrieve the payment and decode the Base64 merchant_data payload.
// Node.js/Express example
app.get('/payment/callback', async (req, res) => {
const { payment_id } = req.query;
const response = await fetch(
`https://api-sbx.globalgetnet.com/dpm/payments-gwproxy/v2/payments/${payment_id}`,
{
headers: {
'authorization': 'Bearer <your-token>',
'x-seller-id': '54f88e68-7764-4e87-8830-756b1e2c02f8'
}
}
);
const payment = await response.json();
if (payment.additional_data?.merchant_data) {
const merchantData = JSON.parse(
Buffer.from(payment.additional_data.merchant_data, 'base64').toString('utf-8')
);
console.log('Decoded payment data:', merchantData);
}
if (payment.status === 'APPROVED' || payment.status === 'CAPTURED') {
res.redirect(`/order/success?order_id=${payment.order_id}`);
} else {
res.redirect(`/order/failed?order_id=${payment.order_id}`);
}
});