Payments with Developer Pay API
IMPORTANT
The Developer Pay API is superseded by the Ecommerce API. Developer Pay apps will no longer be available on the App Market starting October 27, 2021. New Clover apps providing card-not-present payments should use the Ecommerce API instead of Developer Pay.
If you want to migrate an existing Developer Pay app, see Migrating from Developer Pay to Ecommerce.
IMPORTANT NOTICE to Clover Developers
If your published app asks for the process credit card permission, we're trying to contact you about your app's move to the Ecommerce API.
If you haven't received an email from us, please email App Market Business for more information.
With the Developer Pay API (US and Canada), you can build simple payment solutions using the Clover REST API.
The Developer Pay API consists of two endpoints:
GET /v2/merchant/{mId}/pay/key
POST /v2/merchant/{mId}/pay
Limitations of Developer Pay API
Developer Pay supports basic sale transactions; many payment functions available on Clover hardware and in other Clover SDKs are not available with this API.
The following functions are not supported:
- Card vaulting (tokenization) without processing a payment
- Authorizations with tip adjustment
- Pre-authorizations
- Refunds
- Voids
Getting information for the Pay endpoint
GET /v2/merchant/{mId}/pay/key
This endpoint returns the key
and prefix
you'll need to construct a request body for the /pay
endpoint. Prepend the prefix value to the credit card number, and then use RSA/OAEP/SHA1 encryption on the resulting string using the provided modulus and exponent.
Permissions required: Read payments
Parameters: No URL parameters
Request: No request data needed
Response:
{
"pem" : string
"prefix" : string
"modulus" : string //base 10
"exponent" : string
"id" : string
}
Authorizing and capturing a payment
POST /v2/merchant/{mId}/pay
This endpoint authorizes and captures a credit card per the merchant's configuration. An orderId
for an existing order from the Clover API must be included in the payload sent to this endpoint. If this is the first time you're using the card with this specific merchant, you must encrypt the card data with the results from the GET /v2/merchant/{mId}/pay/key
endpoint. After you've made a payment with a card, you'll get a token that can be used for subsequent transactions in place of the cardEncrypted
, cvv
, expMonth
, expYear
, and zip
parameters.
NOTE
In order to use the Developer Pay API to process credit cards, you need an OAuth-generated API token. Merchant-generated API tokens are not supported.
Permissions required: Write payments, Online payments
Parameters: No URL parameters
Request
{
"orderId": "HCFFREA222N02",
"taxAmount": 9,
"zip": "94041",
"expMonth": 1,
"cvv": "111",
"amount": 100,
"currency": "usd",
"last4": "1111",
"expYear": 2015,
"first6": "411111",
"cardEncrypted": "X8UeKej+AEG1h0wD9Xw=="
}
Response
Returns an object that includes result statuses and the ID for the payment object. If the merchant is set up for card tokenization, the response will include a token you can use for subsequent transactions for this particular card and merchant.
{
"authCode" : string
"failureMessage" : string
"token" : string
"result" : (APPROVED|DECLINED)
"avsResult" : (SUCCESS|ZIP_CODE_MATCH|ZIP_CODE_MATCH_ADDRESS_NOT_CHECKED|
ADDRESS_MATCH|ADDRESS_MATCH_ZIP_NOT_CHECKED|NEITHER_MATCH|
SERVICE_FAILURE|SERVICE_UNAVAILABLE|NOT_CHECKED|
ZIP_CODE_NOT_MATCHED_ADDRESS_NOT_CHECKED|
ADDRESS_NOT_MATCHED_ZIP_CODE_NOT_CHECKED)
"paymentId" : string
"cvvResult" : (SUCCESS|FAILURE|NOT_PROCESSED|NOT_PRESENT)
}
Payment flow
- To get the encryption information needed for the
/pay
endpoint, send a GET request to/v2/merchant/{mId}/pay/key
. - Encrypt the card information:
- Prepend the
prefix
value to the card number. - Generate an RSA public key using the
modulus
andexponent
values. - Using the public key, encrypt the combined prefix and card number from step one.
- Base64 encode the resulting encrypted data into a string to be sent in the
cardEncrypted
field.
NOTE
The modulus returned by Clover is in base 10. Various libraries expect moduli in different bases.
- To pay for the order, send a POST request to
/v2/merchant/{mId}/pay
. Pass the encrypted card data and order information in the request.
When the order is paid, the order and payment data are automatically synchronized between the Clover server and the merchant's Clover devices.
Example code
The following encryption example code is from the Java Example App.
public static PublicKey getPublicKey(final BigInteger modulus, final BigInteger exponent) {
try {
final KeyFactory factory = KeyFactory.getInstance("RSA");
final PublicKey publicKey = factory.generatePublic(new RSAPublicKeySpec(modulus, exponent));
return publicKey;
} catch (GeneralSecurityException e) {
throw new BaseException(e);
}
}
public static String encryptPAN(final String prefix, final String pan, PublicKey publicKey) {
byte[] input = String.format("%s%s", prefix, pan).getBytes();
try {
Cipher cipher = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, publicKey, RANDOM);
byte[] cipherText = cipher.doFinal(input);
return DatatypeConverter.printBase64Binary(cipherText);
} catch (GeneralSecurityException ignore) {
return null;
}
}
NOTE
Customer transactions appear with URLs in their credit card statements. We recommend that you limit your app's site URL to thirteen characters. Any additional characters will not appear in statements.
To provide a consistent customer experience while also keeping the site URL short, you can use a URL shortening service.
Payment flow using a vaulted card
Once you complete the steps in the payment flow, you will have a token you can use to process additional transactions if the merchant has been configured to accept vaulted cards. To use this token, build a request in the following format.
{
"orderId": "{{orderId}}", //the Clover order
"currency": "usd",
"amount": 100,
"tipAmount": 0,
"taxAmount": 0,
"first6": "601136",
"last4": "6668",
"vaultedCard": {
"token": "7297162975886668",
"first6": "601136",
"last4": "6668",
"expirationDate": 1219, //expiration in mmdd format
}
}
The vaultedCard
object contains the token returned in the vaultedCard
for the initial payment request. Pay attention to the following when making a payment request with a token:
- The
last4
andfirst6
values need to be in both thevaultedCard
and the main request body - The
expMonth
andexpYear
from the first request need to be combined as a single string as the value ofexpirationDate
Submit the request to the same /v2/merchant/{mId}/pay
endpoint as the original request.
Updated 5 months ago