Skip to content

Card payment with Hosted checkout

A complete card payment built with Hosted checkout: the backend creates a Checkout Session, the page sends the customer to the session's hosted url, and Shift4 returns them to the page once they have paid. It follows the flow described in Hosted checkout.

There is no script, public key, or card field on this page. Shift4 renders and hosts the whole payment step, so card data never reaches the page and Shift4 handles it along with the PCI scope.

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

Potted plant
Qty 1
$24.99

Pay with Hosted checkout

You enter your card details on Shift4's hosted payment page, 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

    Your backend creates a Checkout Session for the order and sets redirectUrl to the page the customer returns to after paying. The response's checkoutSession.url is the Shift4-hosted payment page for this session. See Create a Checkout Session for all the options.

    # 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": "Potted plant",
                "currencyCode": "USD",
                "amount": { "total": 24.99 }
              }
            }
          ],
          "redirectUrl": "https://yourapp.example.com/after-payment"
        }
      }'
  2. 2

    Redirect the customer

    Send the customer's browser to checkoutSession.url, for example by answering the request that created the session with a redirect. The customer enters their payment details on the hosted page; your page needs no script or public key. See Hosted checkout.

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

    Confirm the payment

    After payment, Shift4 redirects the customer to your redirectUrl with status and checkout_session_id appended. The status=success parameter is a convenience signal, not proof of payment. Before you fulfil the order, retrieve the Checkout Session on your backend and check that its status is paid, or receive Checkout Session webhooks so you don't depend on the customer coming back. See Confirm the payment.

    # Shift4 sends the customer back to your redirectUrl:
    # https://yourapp.example.com/after-payment?status=success&checkout_session_id={{checkoutSessionId}}
    
    # Run on your backend: retrieve the Checkout Session and check that its status is paid.
    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}}"