Skip to content

Customer-chosen amount with Hosted checkout

A payment where the customer decides how much to pay, for pay-what-you-want pricing, tips, or donations. The backend creates a Checkout Session whose line item has preset amounts and a custom range instead of a fixed price, and the hosted payment page lets the customer pick one. It follows Amount: fixed or customer-chosen.

Customer-chosen amounts are collected on the hosted page and aren't supported by Payment components yet, so this example uses Hosted checkout. After payment, the backend retrieves the Checkout Session to confirm it.

This example runs in the sandbox. Pay with one of the test cards below; no real payment is made.

Contribution
Qty 1
$1 – $1,000

Pay with Hosted checkout

On Shift4's hosted payment page, pick $5, $10, or $25, or enter any amount from $1 to $1,000, then come back here once the payment is done.

Shift4 hosts the payment page; nothing is embedded here.

Test cards

  • 4242 4242 4242 4242
    Payment succeeds
  • 4024 0071 1846 8684
    Declined: insufficient funds
  • 4012 0001 0000 0114
    Succeeds after frictionless 3D Secure
  • 4012 0018 0000 0016
    Succeeds after a 3D Secure challenge

Use any future expiry date and any 3-digit CVC. More scenarios in Test cards.

How it works

  1. 1

    Create a Checkout Session with a customer-chosen amount

    Instead of a fixed total, give the line item's amount preset amounts in options, a custom range in custom (min and max), or both together to show the presets alongside an “other amount” field. total can't be combined with either. See Amount: fixed or customer-chosen.

    # Run on your backend. SHIFT4_ACCESS_TOKEN is your Access Token - keep it on the server.
    curl -X POST https://api.shift4.com/api/rest/v1/checkoutsessions/create \
      -H "AccessToken: $SHIFT4_ACCESS_TOKEN" \
      -H "InterfaceVersion: 1.0" \
      -H "InterfaceName: YourApp" \
      -H "CompanyName: YourCompany" \
      -H "Content-Type: application/json" \
      -d '{
        "checkoutSession": {
          "lineItems": [
            {
              "product": {
                "name": "Contribution",
                "currencyCode": "USD",
                "amount": {
                  "options": [5, 10, 25],
                  "custom": { "min": 1, "max": 1000 }
                }
              }
            }
          ],
          "redirectUrl": "https://yourapp.example.com/after-payment"
        }
      }'
  2. 2

    Redirect the customer

    Send the customer's browser to checkoutSession.url. The hosted page shows the preset amounts and the custom amount field, and takes the payment. See Hosted checkout.

    HTTP/1.1 303 See Other
    Location: https://pay.shift4.com/chse_wMCUGVZgpf45fWHzKbYWMKmZ
  3. 3

    Confirm the payment and the amount

    The customer, not your backend, chose the amount, so read it from the Checkout Session rather than assuming one. Retrieve the Checkout Session, check that its status is paid, and take the amount from lastTransaction.amount.total. See Confirm the payment.

    # Run on your backend: retrieve the Checkout Session, check that its status is paid,
    # and read the amount the customer chose from lastTransaction.amount.total.
    curl https://api.shift4.com/api/rest/v1/checkoutsessions/retrieve \
      -H "AccessToken: $SHIFT4_ACCESS_TOKEN" \
      -H "InterfaceVersion: 1.0" \
      -H "InterfaceName: YourApp" \
      -H "CompanyName: YourCompany" \
      -H "CheckoutSessionId: {{checkoutSessionId}}"