Accept a Payment Stripe Samples

repository·main·Indexed 21 days ago

https://github.com/stripe-samples/accept-a-payment

Implementation samples for accepting payments on the web using Stripe, featuring a variety of hosted pages and custom UI flows. Includes client implementations for Android (Kotlin), iOS (SwiftUI), React, React Native (Expo), and HTML/JS, with compatible backend server options in Node.js, TypeScript, .NET Core, Go, and Java.

Tokens
56.7K
Snippets
203
Records
254
Agent score
73%

What's inside stripe-samples/accept-a-payment

  1. Explore server-side implementations for Checkout Sessions

    main

    This project provides multiple server-side implementations for handling Checkout Sessions. You can choose an implementation based on your preferred backend language and framework. Each implementation demonstrates how to create a Checkout Session on the server and handle the resulting payment flow.

    Available implementations:
    - Node (Express)
    - Python (Flask)
    - Ruby (Sinatra)
    - PHP
    - Java (Spark)
    - Go
    - .NET (ASP.NET Core)
  2. Inspect Playwright snapshot testing failures

    main

    Playwright tests in this project use visual regression testing. If a test fails, it is because the current screenshot differs from the expected screenshot stored in the *-snapshots/ directory.

    When a failure occurs in CI, you can inspect the following artifacts from the CI run page:

    • The expected screenshot: The baseline image.
    • The actual screenshot: The image captured during the current run.
    • The visual diff: An image highlighting the differences.

    To update the baseline images locally, use the --update-snapshots option with the Playwright command.

  3. Handle Webhooks for asynchronous payment fulfillment

    main

    Since many payment methods (like bank transfers) are asynchronous, you should implement a webhook handler to automate fulfillment (e.g., updating databases, sending emails, or shipping products).

    When receiving a webhook event, you can access the PaymentIntent data via event.data.object. Common event types to monitor include payment_intent.created and various status-related events.

    To test webhooks locally without tunneling software like ngrok, use the Stripe CLI with the listen command. This creates a direct connection from Stripe to your local development server.

    # Listen for webhooks locally
    stripe listen --forward-to localhost:4242/webhook
  4. Choose a Stripe integration method

    main

    Stripe provides different integration paths based on your required level of control and complexity. The two primary APIs are:

    Best for most integrations. It includes built-in support for tax, discounts, shipping, adaptive pricing, recurring payments, localization, and automatic payment methods.

    • Prebuilt Checkout page: A Stripe-hosted page. Lowest complexity. Redirects customers to Stripe and back to your site.
    • Elements with Checkout Sessions: A custom form on your site using ui_mode: 'elements'. Moderate complexity. Customers stay on your site.

    2. Payment Intents API (Direct API)

    Best when you need capabilities beyond what Checkout Sessions provides. Requires more server-side code and does not include built-in tax or easy recurring payment support.

    • Payment Element: A prebuilt UI on your site. Moderate complexity. You manage the payment lifecycle.
    • Custom payment flow: A fully custom checkout using individual Stripe Elements. High complexity. Maximum control over UI and lifecycle.
  5. Handle Alipay redirect URL scheme

    main

    For Alipay's app-to-app redirect to work, your iOS app must have a custom URL scheme configured. This allows the Alipay app to trigger a redirect back into your application after the user authenticates the payment.

    In the provided example, the custom URL scheme is configured as: accept-a-payment://safepay

    Ensure this scheme is registered in your project's Info.plist under URL Types.

  6. Fetch the Stripe Publishable Key via a config endpoint

    main

    Instead of hard-coding your Stripe publishable_key in client-side code (especially in mobile apps), implement a simple GET endpoint (e.g., /config) that returns the key.

    Why this is a best practice: If you need to rotate your API keys, you can update the key on your server. Mobile apps will fetch the new key on their next request, avoiding the need for users to download an app update to receive new credentials.

  7. How confirmCardPayment works

    main

    The confirmCardPayment method is a high-level function provided by Stripe.js that performs several critical actions in a single call:

    1. Tokenization: It sends the raw card details directly from the client to the Stripe API to create a payment method.
    2. Confirmation: It attempts to confirm the PaymentIntent using that payment method.
    3. SCA Handling: If the payment requires Secure Customer Authentication (SCA), confirmCardPayment automatically handles the user experience by opening a modal or redirecting the user to complete the authentication step.

    It resolves with either a paymentIntent object (on success) or an error object (on failure).

  8. Run the Sinatra implementation of Accept a Payment

    main

    This project provides a Sinatra-based Ruby server implementation for accepting payments. To run it locally, you must configure your environment variables, install dependencies via Bundler, and start the server script.

    Prerequisites

    • Ruby v2.4.5 or higher
    • A configured .env file in the current directory

    Setup and Execution

    1. Configure .env: Ensure your .env file contains the necessary Stripe keys and local configuration.
    2. Install dependencies: Run bundle install to install required Ruby gems.
    3. Start the server: Run ruby server.rb.
    4. Access the application: Open http://localhost:4242 in your browser.
    # 1. Configure .env
    STRIPE_PUBLISHABLE_KEY=pk_test...\nSTRIPE_SECRET_KEY=sk_test...\nSTRIPE_WEBHOOK_SECRET=whsec_...\nSTATIC_DIR=../../client/html\nDOMAIN=http://localhost:4242\n\n# 2. Install dependencies\nbundle install\n\n# 3. Run the server\nruby server.rb