Accept payments and tips

United States
Canada

After generating a card token, you can use the source token from Create a charge to create a charge, create and pay for orders, and accept tips. Clover provides several sandbox test cards that can be used when developing your app.

📘

Note

For more information on the accepting payments procedure, refer to create a charge in five minutes.

Pay for a charge

If there is no order associated with a payment, simply create a charge by sending a POST request to the Create a charge endpoint. This is useful for scenarios such as recurring subscriptions.

Using idempotency keys

An idempotency key is a required value generated by your app for Clover to retry Create a charge requests without accidental double charges. If your app uses an idempotency key with a Create a charge request and a network connection error occurs, use the same key to retry the request and prevent any duplicate charges. Your idempotency key must be a version 4 UUID or equivalent. You can generate a key with the Python or Node uuid package.

import uuid
print uuid.uuid4()
import { v4 as uuidv4 } from 'uuid';
uuidv4();

Create a charge intro

When you Create a charge, Clover auto-creates an order. In the following example, set the amount (in cents), source, and currency unit details. Set the authorization header to your OAuth-generated access_token and idempotency-key to your generated uuid4_key.

In the following example, tax is set using the tax_rate_uuid object in the Create a charge endpoint.

curl --request POST \
  --url 'https://scl-sandbox.dev.clover.com/v1/charges' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access_token}' \
  --header 'idempotency-key {uuid4_key}' \
  --header 'content-type: application/json' \
  --header 'x-forwarded-for: {client_ip}' \
  --data '{"amount":1100,
  "currency":"usd",
  "tax_rate_uuid":"{tax_uuid}",
  "Source":"{token}"}'

You can set tax values for the charge amount in two ways:

Tax objectDescription
tax_rate_uuid (recommended)Use tax_rate_uuid to set the tax based on merchant's tax information. This is the recommended approach. Taxes are set under Setup > Taxes & Fees on the merchant's dashboard. You can retrieve this merchant tax information with /v3/merchants/{mId}/tax_rates.
tax_amountUse tax_amount o set a flat fee for tax amount.

📘

NOTE

When adding taxes in your charge request, the amount must be the sum of the items and any tax or tip. For example, if the cost of the item is $10 and the tax is $1. the amount value must be 1100 ($11).

In response, if the payment is successful using the tokenized card (refer to Create a card token, a unique id (charge ID) is generated. The payment status value states whether the payment was successful. If the merchant is set up for credit surcharging, the additional_charges object provides details of the surcharge for the payment.

{
  "id" : "2G1RQC0VTH7WY",
  "amount" : 1100,
  "tax_amount" : 100,
  "amount_refunded" : 0,
  "currency" : "usd",
  "created" : 1623551758243,
  "captured" : true,
  "ref_num" : "116400500490",
  "auth_code" : "OK4447",
  "outcome" : {
    "network_status" : "approved_by_network",
    "type" : "authorized"
  },
  "paid" : true,
  ...
  card source details
  ...
  }
}

Use the Auth & Capture model

Consider a use case where a customer purchases a green t-shirt from a Clover merchant's online shop. You can authorize the customer payment and then capture it when the merchant confirms that the green t-shirt is in stock and is ready for shipping. An authorized payment is a confirmation (from the card-issuing institution) of the cardholder's ability to pay.

To authorize a customer payment, set the capture value to false with a POST request to the /v1/charges endpoint. Set the authorization header to your OAuth-generated access_token.

curl --request POST \
  --url 'https://scl-sandbox.dev.clover.com/v1/charges' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access_token}' \
  --header 'idempotency-key {uuid4_key}' \
  --header 'content-type: application/json' \
  --header 'x-forwarded-for: {client_ip}' \
  --data '{"amount":1100,
  "currency":"usd",
  "tax_rate_uuid":"{tax_uuid}",
  "source":"{token}"
  "Capture":false}'

In response, a unique id (charge ID) is generated. If the merchant is set up for credit surcharging, the additional_charges object provides details of the surcharge for the payment.

📘

NOTE

If an authorized payment is not captured for seven days, authorization is automatically reversed.

When the charge is ready for capture, send a POST request to the /v1/charges/{chargeId}/capture endpoint.

Pay for an order

📘

NOTE

Clover has multiple APIs for creating orders, each with its own advantages and limitations. In most situations, we recommend that you use our Atomic Orders API to create orders. The /atomic_order/orders and /atomic_order/checkouts endpoints provide our most full featured API for creating an order in a single request with line items, modifiers, discounts, etc.

You can use the Ecommerce API v1/orders/{orderId}/pay endpoint to pay for orders created with any of our order APIs.

Step 1: Create an order

To create an order using your tokenized card, create the order with a POST request to the /v1/orders endpoint.

In the following example, set the name, address, and currency unit details for the order. Set the authorization to your OAuth-generated access_token. See the API reference for more information about other values you can set.

curl --request POST \
  --url 'https://scl-sandbox.dev.clover.com/v1/orders' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access_token}' \
  --header 'content-type: application/json' \
  --data '{"currency":"usd",
  "customer":"{customer_uuid}",
  "email":"[email protected]",
  "items":[{"amount":1800,
  "currency":"usd",
  "description":"Test item #1",
  "quantity":1,"type":"sku"
  "tax_rates":[{"name":"Sale","tax_rate_uuid":"{tax_uuid}"}]}],
  "shipping":{"address":{city":"Sunnyvale",
  "country":"US",
  "line1":"415 N Mathilda Ave",
  "postal_code":"94085",
  "state":"California"},"name":"John Doe"}}'

In this example, the item-level tax is set using the tax_rates object. Using v1/orders to create an order, you can set the tax value for each item in three ways.

Tax objectDescription
Tax as UUID (recommended)To set the tax based on merchant tax information, use tax_rate_uuid. This is the recommended approach.
Taxes are set under Setup > Taxes & Fees on the Merchant Dashboard. You can retrieve this merchant tax information with /v3/merchants/{mId}/tax_rates.
Tax as percentageTo set a tax percentage, set the rate as an integer. For example, use 1000000 for a 10% tax.
Tax as amountTo set a flat fee, use tax_amount.

In response, a unique id (order ID) is generated for the created order. The order status value is set to created.

{
  "id" : "96JN5MP2QJ47C", // order ID of the created order
  "object" : "order",
  "amount" : 1980,
  "currency" : "usd",
  "created" : 1623566507000,
  "customer" : "BJA5CF0M0C4ST",
  "email" : "[email protected]",
  "items" : [ {
    "type" : "sku",
    "quantity" : 1,
    "amount" : 1800,
    "currency" : "usd",
    "description" : "Test item #1",
    "tax_rates" : [ {
      "name" : "Sale",
      "tax_rate_uuid" : "77FAGR71YYD5M"
    } ]
  }, {
    "type" : "tax",
    "amount" : 180,
    "description" : "Sales Tax"
  } ],
  ...
  shipping information
  ...
  },
  "status" : "created" // order created
}

📘

NOTE

If you have already built applications using /v3 Clover endpoints (such as Inventory (/v3/merchants/{mId}/items) or Orders (/v3/merchants/{mId}/orders)), it is recommended that you continue using those endpoints.

The /v1/orders endpoint is meant for streamlined app creation and does not include all of the same features. Inventory stock counts are not automatically adjusted with the /v1/orders endpoint.

Step 2: Pay for the created order

To pay for a created order, send a POST request to the /v1/orders/{orderId}/pay endpoint.

In the following example, set the orderId and source values. Set the authorization header to your OAuth-generated access_token. If you include an email address in the request body, a web receipt for the order is sent automatically.

curl --request POST \
  --url 'https://scl-sandbox.dev.clover.com/v1/orders/{orderId}/pay' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access_token}' \
  --header 'content-type: application/json' \
  --header 'x-forwarded-for: {client_ip}' \
  --data '{"source":"{token}","email":"[email protected]"}'

📘

NOTE

In case you are adding a customer while creating an order, you can set the source value to the customer UUID while using the /v1/orders/{orderId}/pay endpoint to pay for the created order.

In response, if the payment is successful using the tokenized card, a unique id (charge ID) is generated. In addition, the order status value is set to paid. If the merchant is set up for credit surcharging, the additional_charges object provides details of the surcharge for the payment.

Submitting multiple payments for an order

In some cases, you may want to pay for an order using more than one card or payment method. For example, a customer may want to pay for part of the order with a gift card and use a credit card for the balance. To process these split payments, you submit multiple requests to the /v1/orders/{orderId}/pay endpoint and specify the amount for each payment.

Example order with two payments

In this example, the customer wants to pay for an order consisting of one $14 item. They will pay using a $10 gift card and a credit card for the remaining $4.

{
  "id": "PND09C6WNW2Y3",
  "object": "order",
  "amount": 1400,
  "currency": "usd",
  "created": 1610131014000,
  "customer": "2S6XE98MP58YE",
  "email": "[email protected]",
  "items": [
    {
    "type" : "sku",
    "quantity" : 1,
    "amount" : 1400,
    "currency" : "usd",
    "description" : "Item"
 		}
  ],
  "shipping": {
    ...
  },
  "status": "created"
}

First, send a POST request to /v1/orders/{orderId}/pay using the gift card as the source and setting the amount as 1000.

{
  "source": "{giftCardToken}"
  "amount": 1000
}

In the response, the amount_paid field shows that $10 have been applied to the $14 order.

{
  "id": "0DHG92XRFFXKP",
  "object": "order",
  "amount": 1400,
  "amount_paid": 1000,
  "currency": "USD",
  "charge": "69Q0S9BK2ZTNA",
  ...
}

Next, send another POST request using the credit card as the source and setting the amount to the remaining 400.

{
  "source": "{creditCardToken}"
  "amount": 400
}

In the response to the second charge, the past_charges shows the first payment made with the gift card. The amount_paid is now 1400 (equal to the total order amount).

{
  "id": "0DHG92XRFFXKP",
  "object": "order",
  "amount": 1400,
  "amount_paid": 1400,
  "currency": "USD",
  "charge": "69Q0S9BK2ZTNA",
  ...
  "past_charges": [
    {
      "id": "EVW3V8TDJQT0C",
      "amount": 1000,
      "currency": "usd",
      ...
    }
  ],
  ...
}

Add tips to charges and orders

You can use the tip_amount (in cents) value to add a tip before paying for a charge (/v1/charges) or an order (/v1/orders/{orderId}/pay). In the following example, an optional tip_amount value is added while paying for a charge:

curl --request POST \
  --url 'https://scl-sandbox.dev.clover.com/v1/charges' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access_token}' \
  --header 'idempotency-key {uuid4_key}' \
  --header 'content-type: application/json' \
  --header 'x-forwarded-for: {client_ip}' \
  --data '{"amount":1800,
  "tip_amount":200,
  "currency":"usd",
  "source":"{token}"}'

Similarly, you can add a tip with a POST request to the /v1/orders/{orderId}/pay endpoint.

📘

NOTE

To help merchants avoid chargebacks, tips are not adjustable and can only be included in the initial request. For instance, you cannot add a tip after an order receipt is printed.

Order calculations with tips

Always submit the charge or order amount and tip separately. In the above example, for a subtotal of $18 and a tip of $2:

SubtotalTip
Correct"amount": 1800"tip_amount": 200
Incorrect"amount": 2000"tip_amount": 200

Set the transaction type indicator

When your app submits a charge, pays for an order, or creates a customer with a card on file, the ecomind parameter can be set to one of two values to indicate who initiated the payment. If no value is set, the default is ecom.

  • ecom - a payment where the customer enters their card details for a single transaction
  • moto - a payment where the merchant enters the customer's card details received over the phone or by mail

ecom

In this example, the customer uses an iframe-based app to submit a charge request for an online ecom payment.

1630

moto

Alternatively, the customer could make their purchase over the phone and provide their card details to the merchant. In that case, the indicator should be set as moto because the merchant is entering the card information on the customer's behalf.

1630

Pay with an alternate tender

If the merchant using your app accepts alternate, non-card tenders (such as cash or check), you can submit charge or order payment requests using these tender types.

Get a merchant's available tenders

You can use the Get a single merchant endpoint to see the custom tenders a merchant accepts. To get the data, you must expand the tenders as shown in the following example.

curl --request GET \
  --url 'https://sandbox.dev.clover.com/v3/merchants/mId?expand=tenders' \
  --header 'Accept: application/json'

In the response, examine the tenders object and note the following important information for each element:

KeyDescription
tenders.elements.idUUID of the tender
tenders.elements.labelKeyInternal name of the tender. Values starting with com.clover.tender are Clover system tenders. Other values are custom tenders.
tenders.elements.labelDisplay name of the tender
tenders.elements.enabledIf true, the tender is currently accepted as payment for transactions

Charge a customer using an alternate tender

Alternate tenders require a different request body but use the same /v1/charges or /v1/order/{orderId}/pay endpoint. The first difference is that the value of the source must be the string alternate_tender. The second difference is that you must include a tender object that identifies the tender being used by label_key, label, or id. label_key is an enumerated field with two possible values that refer to Clover system tenders: com.clover.tender.cash and com.clover.tender.check. If the merchant has enabled any custom tenders, those can be specified with a label or id.

Charge a customer using cash

For example, if you wanted to charge the customer for an in-person cash payment, you could use a request like the following. In this case, the label_key is used to identify the tender selected for the payment.

curl --request POST \
  --url 'https://scl-sandbox.dev.clover.com/v1/charges' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{"tender":{"label_key":"com.clover.tender.cash"},"source":"alternate_tender","currency":"usd","amount":1833}'

Charge a customer using a check

A customer may also pay with a check as a non-card tender. In the following example, notice that the label_key value is com.clover.tender.check.

curl --request POST \
  --url 'https://scl-sandbox.dev.clover.com/v1/charges' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{"tender":{"label_key":"com.clover.tender.check"},"source":"alternate_tender","currency":"usd","amount":6520}'

Charge a customer using a custom tender

When paying for an order using a merchant's custom tender, you construct the request using the tender's id or label. The following examples show how to use each of these fields to specify the tender.

curl --request POST \
  --url' https://scl-sandbox.dev.clover.com/v1/orders/{orderId}/pay' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'x-forwarded-for: {client_ip}' \
  --data '{"tender":{"id":"3ER64K904R7R8"},"source":"alternate_tender"}'
curl --request POST \
  --url https://scl-sandbox.dev.clover.com/v1/orders/{orderId}/pay \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{"tender":{"label":"Gift card"},"source":"alternate_tender"}'