Developer Pay API – US Only

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

US Only

Returns the key and prefix you’ll need for the pay endpoint

Prepend the prefix to the credit card number and then use RSA/OAEP/SHA1 encryption on the resulting string using the provided modulus and exponent. See https://docs.clover.com/faq#how-do-i-use-the-web-api-to-pay-for-an-order

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” of an existing order from the Clover API must be included in the payload sent to this endpoint. If this is the first time you are using this card for this merchant, you must encrypt the card data with the results from GET /v2/merchant/{mId}/pay/key. Once you’ve made a payment with a card, you’ll get back a token that can be used for subsequent transactions in place of cardEncrypted, first6, last4, cvv, expMonth, expYear, and zip. See https://docs.clover.com/faq#how-do-i-use-the-web-api-to-pay-for-an-order

Permissions Required

  • Payments Write
  • Process Credit Cards

Parameters

  • No url parameters

Response Description

Returns an object which includes a result status, the id for the payment object, and a token which can be used for subsequent transactions for this card and this merchant.

Example

  • Request
    {
      "orderId": "HCFFREA222N02", 
      "taxAmount": 9, 
      "zip": "94041", 
      "expMonth": 1, 
      "cvv": "111", 
      "amount": 100, 
      "currency": "usd", 
      "last4": "1111", 
      "token": "HCFFEAC222N02", 
      "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. GET to /v2/merchant/{mId}/pay/key To get the encryption information you’ll need for the pay endpoint.
  2. Encrypt the card information
    1. Prepend the card number with the prefix fromGET /v2/merchant/{mId}/pay/key.
    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. POST to /v2/merchant/{mId}/pay Pass the encrypted card data and order information to Clover in order to pay for the order.

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 –¬†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;
   }
 }