Skip to content
Create account
or
Sign in
The Stripe Docs logo
/
Ask AI
Create account
Sign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer resources
Overview
About Stripe payments
Upgrade your integration
Payments analytics
Online payments
OverviewFind your use caseManaged Payments
Use Payment Links
Build a checkout page
Build an advanced integration
Build an in-app integration
Payment methods
Add payment methods
    Overview
    Payment method integration options
    Manage default payment methods in the Dashboard
    Payment method types
    Cards
    Pay with Stripe balance
    Crypto
    Bank debits
    Bank redirects
    Bank transfers
    Credit transfers (Sources)
    Buy now, pay later
    Real-time payments
    Vouchers
      Boleto
      Konbini
      Multibanco
        Accept a payment
      OXXO
    Wallets
    Enable local payment methods by country
    Custom payment methods
Manage payment methods
Faster checkout with Link
Payment interfaces
Payment Links
Checkout
Web Elements
In-app Elements
Payment scenarios
Handle multiple currencies
Custom payment flows
Flexible acquiring
Orchestration
In-person payments
Terminal
Beyond payments
Incorporate your company
Crypto
Financial Connections
Climate
HomePaymentsAdd payment methodsVouchersMultibanco

Accept a Multibanco payment

Learn how to accept the Multibanco payment method.

Caution

We recommend that you follow the Accept a payment guide unless you need to use manual server-side confirmation, or your integration requires presenting payment methods separately. If you’ve already integrated with Elements, see the Payment Element migration guide.

Multibanco is a voucher-based payment method in Portugal. If your business is based in Europe or the United States, you can accept Multibanco payments from customers in Portugal using the Payment Intents API.

To complete a transaction, customers receive a voucher that includes Multibanco entity and reference numbers. Customers use these voucher details to make a payment outside your checkout flow through online banking or from an ATM.

Payment confirmation might be delayed by several days due to the initiation of a bank transfer when a customer pays for a Multibanco voucher. Bank transfers can encounter delays, particularly over weekends, contributing to the delay in payment confirmation.

Set up Stripe
Server-side

First, you need a Stripe account. Register now.

To access the Stripe API from your application, use our official libraries:

Command Line
Ruby
# Available as a gem sudo gem install stripe
Gemfile
Ruby
# If you use bundler, you can add this line to your Gemfile gem 'stripe'

Create a PaymentIntent
Server-side

Stripe uses a PaymentIntent object to represent your intent to collect payment from a customer, tracking state changes from Multibanco voucher creation to payment completion.

Create a PaymentIntent on your server with an amount and the eur currency (Multibanco doesn’t support other currencies). If you already have an integration using the Payment Intents API, add multibanco to the list of payment method types for your PaymentIntent.

Command Line
cURL
curl https://api.stripe.com/v1/payment_intents \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d amount=1099 \ -d currency=eur \ -d "payment_method_types[]"=multibanco

Retrieve the client secret

The PaymentIntent includes a client secret that the client side uses to securely complete the payment process. You can use different approaches to pass the client secret to the client side.

Retrieve the client secret from an endpoint on your server, using the browser’s fetch function. This approach is best if your client side is a single-page application, particularly one built with a modern frontend framework like React. Create the server endpoint that serves the client secret:

main.rb
Ruby
get '/secret' do intent = # ... Create or retrieve the PaymentIntent {client_secret: intent.client_secret}.to_json end

And then fetch the client secret with JavaScript on the client side:

(async () => { const response = await fetch('/secret'); const {client_secret: clientSecret} = await response.json(); // Render the form using the clientSecret })();

Collect payment method details
Client-side

Create a payment form on your client to collect the required billing details from the customer:

FieldValue
emailThe full email address of the customer.
checkout.html
<form id="payment-form"> <div class="form-row"> <label for="email"> Email </label> <input id="email" name="email" required /> </div> <!-- Used to display form errors. --> <div id="error-message" role="alert"></div> <button id="submit-button">Pay with Multibanco</button> </form>

Submit the payment to Stripe
Client-side

When a customer clicks to pay with Multibanco, use Stripe.js to submit the payment to Stripe. Stripe.js is our foundational JavaScript library for building payment flows.

Include the Stripe.js script on your checkout page by adding it to the head of your HTML file.

checkout.html
<head> <title>Checkout</title> <script src="https://js.stripe.com/basil/stripe.js"></script> </head>

Create an instance of Stripe.js with the following JavaScript on your checkout page.

client.js
// Set your publishable key. Remember to switch to your live publishable key in production! // See your keys here: https://dashboard.stripe.com/apikeys const stripe = Stripe(
'pk_test_TYooMQauvdEDq54NiTphI7jx'
);

Submit the customer’s billing details by calling by calling stripe.confirmMultibancoPayment with the client secret of the PaymentIntent object that you created.

After confirmation, Stripe automatically opens a modal to display the Multibanco voucher to your customer.

client.js
const form = document.getElementById('payment-form'); form.addEventListener('submit', async (event) => { event.preventDefault(); const result = await stripe.confirmMultibancoPayment( '{{PAYMENT_INTENT_CLIENT_SECRET}}', { payment_method: { billing_details: { email: document.getElementById('email').value, }, }, }); // Stripe.js will open a modal to display the Multibanco voucher to your customer // This async function finishes when the customer closes the modal if (result.error) { // Display error to your customer const errorMsg = document.getElementById('error-message'); errorMsg.innerText = result.error.message; } });

Note

stripe.confirmMultibancoPayment might take several seconds to complete. During that time, disable your form from being resubmitted and show a waiting indicator, such as a spinner. If you receive an error, display it to the customer, re-enable the form, and hide the waiting indicator.

When a Multibanco voucher is created successfully, the value of the returned PaymentIntent’s status property is requires_action. Check the status of a PaymentIntent in the Dashboard or by inspecting the status property on the object. If the Multibanco voucher wasn’t created successfully, inspect the returned error to determine the cause (for example, an invalid email format).

Stripe sends a payment_intent.requires_action event when a Multibanco voucher is created successfully. If you need to send an email with the voucher’s payment instructions link, you can locate the hosted_voucher_url at payment_intent.next_action.multibanco_display_details.hosted_voucher_url.

OptionalSubmit the payment to Stripe from your server
Server-side

OptionalDisplay the Multibanco details to your customer
Client-side

OptionalSend automated payment instruction emails

OptionalCustomize voucher appearance

Handle post-payment events
Server-side

Multibanco is a delayed notification payment method. A customer pays for a Multibanco voucher outside your checkout flow through online banking or from an ATM.

After a Multibanco payment completes, Stripe sends a payment_intent.succeeded event. Use the Dashboard or build a webhook handler to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or initiating a shipping workflow.

Learn about Multibanco expiration.

EventDescriptionNext steps
payment_intent.requires_actionThe Multibanco voucher is created successfully.Wait for the customer to pay for the Multibanco voucher.
payment_intent.processingThe customer can no longer pay for the Multibanco voucher.Wait for the initiated payment to succeed or fail.
payment_intent.succeededThe customer paid for the Multibanco voucher.Fulfill the goods or services that the customer purchased.
payment_intent.payment_failedThe customer did not pay for the Multibanco voucher.Contact the customer through email or push notification and request another payment method.

Receive events and run business actions

Manually

Use the Stripe Dashboard to view all your Stripe payments, send email receipts, handle payouts, or retry failed payments.

View your test payments in the Dashboard.

Custom Code

Build a webhook handler to listen for events and build custom asynchronous payment flows. Test and debug your webhook integration locally with the Stripe CLI.

Learn how to build a custom webhook.

Test the integration

In a sandbox, set payment_method.billing_details.email to the following values when you call stripe.confirmMultibancoPayment to test different scenarios.

EmailDescription

{any_prefix}@{any_domain}

Simulates a Multibanco voucher that a customer pays. The payment_intent.succeeded webhook arrives after about 3 minutes.

Example: jenny@example.com

{any_prefix}succeed_immediately@{any_domain}

Simulates a Multibanco voucher that a customer pays immediately. The payment_intent.succeeded webhook arrives within several seconds.

Example: succeed_immediately@example.com

{any_prefix}expire_immediately@{any_domain}

Simulates a Multibanco voucher that expires immediately. The payment_intent.payment_failed webhook arrives within several seconds.

Example: expire_immediately@example.com

{any_prefix}expire_with_delay@{any_domain}

Simulates a Multibanco voucher that expires before a customer pays. The payment_intent.payment_failed webhook arrives after about 3 minutes.

Example: expire_with_delay@example.com

{any_prefix}fill_never@{any_domain}

Simulates a Multibanco voucher that never succeeds. The payment_intent.payment_failed webhook arrives after 11 days, which mimics behavior in live mode. Learn about Multibanco expiration.

Example: fill_never@example.com

Expiration

Multibanco vouchers expire at the expires_at UNIX timestamp in next_action.multibanco_display_details.expires_at, which is 7 days after you create the voucher. Customers can’t pay a Multibanco voucher after it expires. After expiration, the PaymentIntent’s status transitions from requires_action to processing, and Stripe sends a payment_intent.processing event.

The PaymentIntent remains in the processing status for a maximum buffer period of 4 days to allow for potential completed payment notification delays caused by bank-transfer delays. If the Multibanco payment doesn’t complete within the buffer period, the PaymentIntent’s status transitions to requires_payment_method and Stripe sends a payment_intent.payment_failed event. If you receive the customer’s funds after the buffer period, Stripe automatically initiates a refund process for the mispaid amount.

Cancelation

You can cancel Multibanco vouchers using Cancel a PaymentIntent. After cancelation, Stripe sends a payment_intent.canceled event.

If a customer’s funds are received for a canceled Multibanco voucher, Stripe automatically initiates a refund process for the mispaid amount.

Note

Canceling a pending payment invalidates the original voucher instructions. When you cancel a pending Multibanco payment, inform your customer.

When you successfully reconfirm a PaymentIntent in status requires_action, Stripe creates new voucher instructions and a new hosted_voucher_url. You must provide them to your customer.

Refunds

Learn about Multibanco refunds.

Was this page helpful?
YesNo
Need help? Contact Support.
Join our early access program.
Check out our changelog.
Questions? Contact Sales.
LLM? Read llms.txt.
Powered by Markdoc