Checkout

See the component in action in the live demo.

Step 1: Create a payment session (Server)

In your server-side code, call createPaymentSession in the GraphQL API.

Example

curl -X POST https://GRAPH_URL \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "query": "mutation CreatePaymentSession($input: CreatePaymentSessionInput!) { createPaymentSession(input: $input) { id orgId status amount currency callbackUrl successUrl link contactId contactRef { contactId contactName contactEmail contactPhone } transactionRef invoiceIds invoiceRefs { orderId invoiceId invoiceNumber amount lines { num quantity price productId productSku productName productDescription productImageUrl } } expirationDate paymentId createdAt updatedAt checkoutConfigurationId } }",
    "variables": {
      "input": {
        "orgId": "35dHMM4pFzIykUsys1CDyZ9Xtkz",
        "amount": "4350.00",
        "currency": "USD",
        "contactRef": {
          "contactEmail": "jim@example.com",
          "contactName": "Jim Kirk"
        },
        "invoiceRefs": [
          {
            "amount": "4350.00",
            "invoiceNumber": "INV-12345",
            "lines": [
              {
                "num": 1,
                "price": "3500.00",
                "productDescription": "Premium maple shaker-style kitchen cabinet set: 12 base cabinets, 8 wall cabinets, and pantry unit",
                "productName": "Custom Kitchen Cabinet Set",
                "productSku": "SKU-CAB-KIT-001",
                "quantity": 1
              },
              {
                "num": 2,
                "price": "850.00",
                "productDescription": "Professional installation including leveling, mounting, hardware installation, and final adjustments",
                "productName": "Cabinet Installation Service",
                "productSku": "SKU-INSTALL-001",
                "quantity": 1
              }
            ]
          }
        ]
      }
    }
  }'

Step 2: Load the checkout session component (Client)

In your client-side code, load the checkout script ideally in the <head> of your page.

<script type="module" src="https://js.clientloop.com/checkout.iife.js"></script>

Then, use the checkout session component to render the checkout session using the payment session ID from Step 1.

<checkout-session
  payment-session-id="PAYMENT_SESSION_ID"
></checkout-session>

By default <checkout-session> talks to ClientLoop production. To test your integration against the ClientLoop staging environment, set the optional env attribute to stage:

<checkout-session
  payment-session-id="PAYMENT_SESSION_ID"
  env="stage"
></checkout-session>

Omit env (or set it to prod) for production.

When only one payment method is configured, it is expanded automatically so the customer does not have to open it. Set the optional suppress-autoexpand attribute to true to keep it collapsed until they click it:

<checkout-session
  payment-session-id="PAYMENT_SESSION_ID"
  suppress-autoexpand="true"
></checkout-session>

It defaults to false.

Step 3: Show the customer payment success (Client)

Option 1: Success URL Redirect

If you populated the successUrl in the payment session, the customer will automatically be redirected to the success URL when the payment is completed.

Option 2: Event Listener

If you did not populate a successUrl in the payment session a checkout-with-payment-success event will bubble up to the <checkout-session> component. You can listen for this event and show a success message to the customer.

Usage:

<script>
  // Listen for the checkout-with-payment-success event
  const checkoutSession = document.querySelector('checkout-session');
  if (checkoutSession) {
    checkoutSession.addEventListener('checkout-with-payment-success', (event) => {
      // YOU DO YOUR WORK HERE ON SUCCESS
    });
  }
</script>

Example:

<script>
  // Listen for the checkout-with-payment-success event
  const checkoutSession = document.querySelector('checkout-session');
  const checkoutContainer = document.getElementById('checkout-container');
  const paymentSuccessView = document.getElementById('payment-success');
  if (checkoutSession) {
    checkoutSession.addEventListener('checkout-with-payment-success', (event) => {
      // Hide the checkout session
      if (checkoutContainer) {
        checkoutContainer.classList.add('hidden');
      }
      // Show the payment success view
      if (paymentSuccessView) {
        paymentSuccessView.classList.remove('hidden');
      }
    });
  }
</script>

Step 4: Receive payment confirmation (Server)

If you populated the callbackUrl in the payment session, when you created it, you will receive a webhook notification when the payment is successful.

You may also specify a webhook URL in your configuration settings in the Operations Console.

Be aware if you both pass a callbackUrl in the payment session and have one set in the Operations Console, you will receive multiple events.

The following are examples of the events in order you will receive:

Example: Notification the status on the payment session has been changed.

{
  "events": [
    {
      "type": "PaymentSessionStatusChanged",
      "id": "ps38criWpTCSDSMEXcpX434ETpJ0n",
      "orgId": "35dHMM4pFzIykUsys1CDyZ9Xtkz",
      "oldStatus": "Active",
      "newStatus": "Completed"
    }
  ]
}

Example: Notification the payment record has been created.

{
  "events": [
    {
      "type": "PaymentCreated",
      "id": "38crhYn0Rs9ssu1qYToJtpxiNga",
      "orgId": "35dHMM4pFzIykUsys1CDyZ9Xtkz"
    }
  ]
}

Example: Notification the payment record has had it's status changed

{
  "events": [
    {
      "type": "PaymentStatusChanged",
      "id": "38crhYn0Rs9ssu1qYToJtpxiNga",
      "orgId": "35dHMM4pFzIykUsys1CDyZ9Xtkz",
      "oldStatus": "Pending",
      "newStatus": "Completed"
    }
  ]
}