Developer Pay API (US only)

GET /v2/merchant/{mId}/pay/key

United States only

This endpoint returns the key and prefix you’ll need for the pay endpoint. Prepend the prefix to the credit card number, then use RSA/OAEP/SHA1 encryption on the resulting string using the provided modulus and exponent. See the FAQ for more information.

Permissions required

  • Payments Read

Parameters

  • No URL parameters

Example

Request:

No Request Data Needed.

Response:

{
  "pem" : String
  "prefix" : String
  "modulus" : String
  "exponent" : String
  "id" : String
}

POST /v2/merchant/{mId}/pay

Developer Pay API

This endpoint authorizes and/or captures a credit card per the merchant 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. Once 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, first6, last4, cvv, expMonth, expYear, and zip parameters. See the FAQ for more information.

Note

In order to use the Developer Pay API to process credit cards, you will need an OAuth-generated API token. Merchant-generated API tokens are not supported.

Permissions required

  • Payments Write
  • Process Credit Cards

Parameters

  • No URL parameters

Response description

Returns an object that includes a result status, the ID for the payment object, and a token you can use for subsequent transactions for this particular card and merchant.

Example

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:

{
  "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)
}

Example payment flow

  1. To get the encryption information you’ll need for the pay endpoint, send a GET request to /v2/merchant/{mId}/pay/key.
  2. Encrypt the card information.
    1. Prepend the card number with the prefix from the GET /v2/merchant/{mId}/pay/key call.
    2. Generate an RSA public key using the modulus and exponent provided byGET /v2/merchant/{mId}/pay/key.

      NOTE

      The modulus returned by Clover is in base 10. Various libraries expect moduli in different bases.

    3. Encrypt the card number and prefix from step 1 with the public key.
    4. Base64 encode the resulting encrypted data into a string which you will send to Clover in the cardEncrypted field.
  3. To pay for the order, send a POST request to /v2/merchant/{mId}/pay. Pass the encrypted card data and order information to Clover 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 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;
   }
 }