# MobilePay payments Learn how to accept MobilePay, a popular payment method in Denmark and Finland. # Direct API MobilePay is a [single-use](https://docs.stripe.com/payments/payment-methods.md#usage) card wallet payment method used in Denmark and Finland. It allows your customer to [authenticate and approve](https://docs.stripe.com/payments/payment-methods.md#customer-actions) payments using the MobilePay app. When your customer pays with MobilePay, Stripe performs a card transaction using the card data we receive from MobilePay. The processing of the card transaction is invisible to your integration, and Stripe [immediately notifies you](https://docs.stripe.com/payments/payment-methods.md#payment-notification) whether the payment succeeded or failed. ## Set up Stripe [Server-side] First, you need a Stripe account. [Register now](https://dashboard.stripe.com/register). Use our official libraries for access to the Stripe API from your application: #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ## Create a PaymentIntent [Server-side] A [PaymentIntent](https://docs.stripe.com/api/payment_intents/object.md) is an object that represents your intent to collect a payment from a customer and tracks the lifecycle of the payment process through each stage. Create a `PaymentIntent` on your server and specify the amount to collect and a supported currency (`eur`, `dkk`, `sek`, or `nok`). When using [dynamic payment methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md), eligible payment methods display automatically. ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=dkk \ -d "automatic_payment_methods[enabled]=true" \ -d "payment_method_data[type]=mobilepay" ``` ### Example response ```json { "id": "pi_12345", "amount": 1099, "client_secret": "pi_12345_secret_abcdef", "currency": "dkk", "payment_method": "pm_12345", "payment_method_types": [ "mobilepay" ], "status": "requires_confirmation" } ``` ### Retrieve the client secret The PaymentIntent includes a *client secret* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) 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. #### Single-page application 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: #### Ruby ```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: ```javascript (async () => { const response = await fetch('/secret'); const {client_secret: clientSecret} = await response.json(); // Render the form using the clientSecret })(); ``` #### Server-side rendering Pass the client secret to the client from your server. This approach works best if your application generates static content on the server before sending it to the browser. Add the [client_secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) in your checkout form. In your server-side code, retrieve the client secret from the PaymentIntent: #### Ruby ```erb
``` ```ruby get '/checkout' do @intent = # ... Fetch or create the PaymentIntent erb :checkout end ``` ## Confirm the PaymentIntent Use the PaymentIntent [ID](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-id) from [step 2](https://docs.stripe.com/payments/mobilepay/accept-a-payment.md#create-payment-intent) to *confirm* (Confirming an intent indicates that the customer intends to use the current or provided payment method. Upon confirmation, the intent attempts to initiate the portions of the flow that have real-world side effects) the PaymentIntent. This declares that the customer intends to pay with the specified *PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs). Stripe initiates a payment after confirming the PaymentIntent. The [return_url](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-return_url) indicates where Stripe redirects the customer after they complete the payment. ```curl curl https://api.stripe.com/v1/payment_intents/{{PAYMENTINTENT_ID}}/confirm \ -u "<>:" \ --data-urlencode "return_url=https://example.com/checkout/complete" ``` ### Example response ```json { "id": "pi_12345", "amount": 1099, "currency": "dkk", "payment_method": "pm_12345", "next_action": { "redirect_to_url": { "return_url": "https://example.com/checkout/complete", "url": "https://pm-redirects.stripe.com/authorize/acct_123/pa_nonce_abc" }, "type": "redirect_to_url" }, "payment_method_types": [ "mobilepay" ], "status": "requires_action" } ``` To authorize the payment, redirect your customer to the URL in the [next_action[redirect_to_url][url]](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-redirect_to_url-url) field. - On desktop, the URL opens a MobilePay landing page where the customer can enter their phone number, which identifies their MobilePay account. They can then use the MobilePay smartphone app to proceed with payment authorization. - On mobile devices, the URL opens the MobilePay application directly (if present) or directs to the MobilePay landing page, similar to the desktop process. Your customer has 5 minutes to open the redirect URL and authorize the payment in the MobilePay app. If the underlying card charge fails, your customer can choose a different card and retry in the MobilePay app. If the payment isn’t authorized within 5 minutes, the payment fails and the PaymentIntent’s status transitions to `requires_payment_method`. ## Handle post-payment events Stripe sends a [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) event when the payment completes. Use the Dashboard, a custom *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests), or a partner solution to receive these events and run actions, like sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events also helps you accept more payment methods in the future. Learn about the [differences between all supported payment methods](https://stripe.com/payments/payment-methods-guide). - **Handle events manually in the Dashboard** Use the Dashboard to [View your test payments in the Dashboard](https://dashboard.stripe.com/test/payments), send email receipts, handle payouts, or retry failed payments. - **Build a custom webhook** [Build a custom webhook](https://docs.stripe.com/webhooks/handling-payment-events.md#build-your-own-webhook) handler to listen for events and build custom asynchronous payment flows. Test and debug your webhook integration locally with the Stripe CLI. - **Integrate a prebuilt app** Handle common business events, such as [automation](https://stripe.partners/?f_category=automation) or [marketing and sales](https://stripe.partners/?f_category=marketing-and-sales), by integrating a partner application. ## Test the integration Using your [test API keys](https://docs.stripe.com/keys.md#test-live-modes), create a PaymentIntent. After confirming the PaymentIntent, follow the `next_action` redirect URL to a test page with options to authorize or fail the payment. - Click **Authorize test payment** to test the case when the payment is successful. The PaymentIntent transitions from `requires_action` to `succeeded`. - Click **Fail test payment** to test the case when the customer fails to authenticate. The PaymentIntent transitions from `requires_action` to `requires_payment_method`. ## Optional: Authorize a payment and then capture later MobilePay supports [separate authorization and capture](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md). ### Tell Stripe to authorize only To indicate that you want separate authorization and capture, set [capture_method](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-capture_method) to `manual` when creating the PaymentIntent. This parameter instructs Stripe to only authorize the amount on the customer’s card linked to MobilePay. ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=dkk \ -d capture_method=manual \ -d "automatic_payment_methods[enabled]=true" \ -d "payment_method_data[type]=mobilepay" ``` After the authorization is successful, Stripe sends a [payment_intent.amount_capturable_updated](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.amount_capturable_updated) event. See [Events](https://docs.stripe.com/api/events.md) to learn more. ### Capture the funds After the authorization succeeds, the PaymentIntent’s [status](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-status) transitions to `requires_capture` and you can [capture](https://docs.stripe.com/api/payment_intents/capture.md) the authorized funds. Stripe only support manual captures of the full amount. ```curl curl https://api.stripe.com/v1/payment_intents/{{PAYMENTINTENT_ID}}/capture \ -u "<>:" \ -d amount_to_capture=1099 ``` ## Optional: Cancellation You can cancel MobilePay payments before they expire by [canceling the PaymentIntent](https://docs.stripe.com/api/payment_intents/cancel.md) associated with the MobilePay payment. ## Failed payments MobilePay transactions can fail if the underlying card transaction is declined. Learn more about [card declines](https://docs.stripe.com/declines/card.md). In this case, the PaymentMethod is detached and the PaymentIntent’s status automatically transitions to `requires_payment_method`. When the PaymentIntent’s status is `requires_action`, your customer must authenticate the payment within 5 minutes. If no action is taken after 5 minutes, the PaymentMethod detaches and the PaymentIntent’s status automatically transitions to `requires_payment_method`. ## Refunds and disputes Stripe performs a card transaction using standard card rails as part of a MobilePay transaction. [Refunds](https://docs.stripe.com/refunds.md) and [disputes](https://docs.stripe.com/disputes/how-disputes-work.md) are subject to the Visa and Mastercard network rules.