Accepting payments and tips

After generating a card token, you can use the source token 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.

Paying for a charge

If there is no order associated with a payment, simply create a charge by sending a POST request to the /v1/charges 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 safely retry /v1/charges requests without accidental double charges.

If your app uses an idempotency key with a /v1/charges 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();

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.

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' \
  --data '{"amount":1100,
  "currency":"usd",
  "tax_rate_uuid":"{tax_uuid}",
  "source":"{token}"}'

In this example, tax is set using the tax_rate_uuid object. Using v1/charges to create a charge, you can set tax values for the charge amount in two ways.

Tax object

Description

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 amount

To set a flat fee, use 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, 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. See Working with transaction data (Ecommerce API) for more information.

{
  "id" : "2G1RQC0VTH7WY",
  "amount" : 1100,  // (item cost + tax)
  "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
  ...
  }
}

Using 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' \
  --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. See Working with transaction data (Ecommerce API) for more information.

📘

NOTE

If an authorized payment is left un-captured for seven days, the authorization is automatically reversed.

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

Paying for an order

Step 01: Creating 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 object

Description

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 percentage

To set a tax percentage, set the rate as an integer. For example, use 1000000 for a 10% tax.

Tax as amount

To 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 02: Paying 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' \
  --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. See Working with transaction data (Ecommerce API) for more information.

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",
      ...
    }
  ],
  ...
}

Adding 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' \
  --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:

Subtotal

Tip

Correct

"amount": 1800

"tip_amount": 200

Incorrect

"amount": 2000

"tip_amount": 200

Setting 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.

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.

Paying 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.

Getting 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:

Key

Description

tenders.elements.id

UUID of the tender

tenders.elements.labelKey

Internal name of the tender. Values starting with com.clover.tender are Clover system tenders. Other values are custom tenders.

tenders.elements.label

Display name of the tender

tenders.elements.enabled

If true, the tender is currently accepted as payment for transactions

Charging 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.

Charging 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}'

Charging 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}'

Charging 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' \
  --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"}'

Did this page help you?