Pay by Points — Integration Steps

Step-by-step guide to integrate Pay by Points via Seamless Checkout using Pine Labs Online APIs.

Integration Steps — Custom Checkout

Integrate Pay by Points into your custom checkout using Pine Labs Online APIs.

Follow these steps to enable customers to redeem reward points during payment.

  1. Generate Token
  2. Check Point Balance
  3. Create Order
  4. Create Payment
  5. Handle Payment
  6. Capture Order
  7. Cancel Order

Note:

  • Store your Client ID and Secret in your backend securely.
  • Integrate APIs on your backend system — never call from the frontend.
  • Seamless checkout requires PCI compliance.

1. [Prerequisite] Generate Token

Generate an access token to authenticate all subsequent API calls.

Endpoint: POST /api/auth/v1/token

Bash
curl --location 'https://pluraluat.v2.pinepg.in/api/auth/v1/token' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'Request-Timestamp: 2024-07-09T07:57:08.022Z' \
--header 'Request-ID: c17ce30f-f88e-4f81-ada1-c3b4909ed235' \
--data '{
  "client_id": "<your_client_id>",
  "client_secret": "<your_client_secret>",
  "grant_type": "client_credentials"
}'

Refer to the Generate Token API documentation for full request and response details.


2. Check Point Balance

Query the customer's reward points balance before creating a payment.

Endpoint: POST /payment-option

Bash
curl --location 'https://pluraluat.v2.pinepg.in/payment-option' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--data '{
  "points_card_details": {
    "card_last4": "1234",
    "card_number": "4111111111111234",
    "registered_mobile_number": "9876543210"
  },
  "order_details": {
    "order_amount": {
      "value": 5000,
      "currency": "INR"
    }
  }
}'

The response includes:

FieldDescription
points_balanceNumber of reward points available
inr_equivalentConverted INR amount
conversion_ratePoints-to-INR rate

Customer consent: You must obtain explicit customer consent before proceeding to redeem points. This is mandatory per partner bank requirements.


3. Create Order

Create an order with POINTS included in the allowed payment methods.

Endpoint: POST /api/pay/v1/orders

Bash
curl --location 'https://pluraluat.v2.pinepg.in/api/pay/v1/orders' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--header 'Request-ID: c17ce30f-f88e-4f81-ada1-c3b4909ed235' \
--header 'Request-Timestamp: 2024-07-09T07:57:08.022Z' \
--data '{
  "merchant_order_reference": "PBP-12345",
  "order_amount": {
    "value": 4573,
    "currency": "INR"
  },
  "pre_auth": false,
  "allowed_payment_methods": [
    "CARD",
    "POINTS"
  ],
  "notes": "Pay by Points order",
  "callback_url": "https://your-domain.com/callback",
  "failure_callback_url": "https://your-domain.com/failure",
  "purchase_details": {
    "customer": {
      "email_id": "customer@example.com",
      "first_name": "Kevin",
      "last_name": "Bob",
      "customer_id": "CUST-001",
      "mobile_number": "9876543210",
      "country_code": "91"
    }
  }
}'

Include "POINTS" in the allowed_payment_methods array to enable Pay by Points for this order.

Refer to the Create Order API documentation for the full parameter list.


4. Create Payment

Submit a split payment with both CARD and POINTS components. The amounts must total the order value.

Endpoint: POST /api/pay/v1/orders/{order_id}/payments

Bash
curl --location 'https://pluraluat.v2.pinepg.in/api/pay/v1/orders/{order_id}/payments' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--header 'Request-ID: c17ce30f-f88e-4f81-ada1-c3b4909ed235' \
--header 'Request-Timestamp: 2024-07-09T07:57:08.022Z' \
--data '{
  "payments": [
    {
      "merchant_payment_reference": "pay-card-ref-001",
      "payment_method": "CARD",
      "payment_amount": {
        "value": 1372,
        "currency": "INR"
      }
    },
    {
      "merchant_payment_reference": "pay-points-ref-001",
      "payment_method": "POINTS",
      "payment_amount": {
        "value": 3201,
        "currency": "INR"
      },
      "points_card_details": {
        "card_last4": "1234",
        "card_number": "4111111111111234",
        "registered_mobile_number": "9876543210"
      }
    }
  ]
}'

Split payment example

ComponentAmountDescription
Card₹13.72Paid via credit/debit card
Points₹32.01Redeemed from reward points
Total₹45.73Must match order amount

Important: The sum of all payment amounts must exactly equal the order amount. Mismatched amounts will cause the payment to fail.

Refer to the Create Payment API documentation for all parameters.


5. Handle Payment

The Create Payment response returns a challenge_url. Redirect the customer to this URL to complete authentication.

Redirect flow

  1. Redirect the customer to challenge_url
  2. Customer completes authentication on the bank page
  3. Bank redirects back to your callback_url with payment details

Callback response

On successful payment:

JSON
{
  "order_id": "v1-4405071524-aa-qlAtAf",
  "payment_status": "AUTHORIZED",
  "signature": "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
}

Verify signature (mandatory)

Generate a SHA256 HMAC signature on your server and compare it with the returned signature.

Signature string format:

Code
order_id=<order_id>&status=AUTHORIZED

Signature verification (Java):

Java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class SignatureVerifier {
    public static String generateHash(String input, String secretKey) {
        try {
            byte[] keyBytes = new byte[secretKey.length() / 2];
            for (int i = 0; i < secretKey.length() / 2; i++) {
                keyBytes[i] = (byte) Integer.parseInt(
                    secretKey.substring(i * 2, (i * 2) + 2), 16
                );
            }
            SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "HmacSHA256");
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(keySpec);
            byte[] hashBytes = mac.doFinal(input.getBytes("UTF-8"));

            StringBuilder hash = new StringBuilder();
            for (byte b : hashBytes) {
                String hex = Integer.toHexString(0xFF & b);
                if (hex.length() == 1) hash.append('0');
                hash.append(hex);
            }
            return hash.toString().toUpperCase();
        } catch (Exception e) {
            return "";
        }
    }
}

Security: Always verify the signature before processing the order. This confirms the payment response is authentic and has not been tampered with.


6. Capture Order

After successful payment and signature verification, capture the order to complete the transaction.

Endpoint: PUT /api/pay/v1/orders/{order_id}/capture

Bash
curl --location --request PUT \
'https://pluraluat.v2.pinepg.in/api/pay/v1/orders/{order_id}/capture' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--header 'Request-ID: c17ce30f-f88e-4f81-ada1-c3b4909ed235' \
--header 'Request-Timestamp: 2024-07-09T07:57:08.022Z'

Capture is only available when the order status is AUTHORIZED.


7. Cancel Order (optional)

Cancel an authorized order if you do not wish to capture the payment.

Endpoint: PUT /api/pay/v1/orders/{order_id}/cancel

Bash
curl --location --request PUT \
'https://pluraluat.v2.pinepg.in/api/pay/v1/orders/{order_id}/cancel' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--header 'Request-ID: c17ce30f-f88e-4f81-ada1-c3b4909ed235' \
--header 'Request-Timestamp: 2024-07-09T07:57:08.022Z'

Cancel is only available when the order status is AUTHORIZED.


Best Practices

PracticeDetail
Verify signatureAlways verify the callback signature using SHA256 HMAC — this is mandatory
Fetch order statusUse Get Order API from your backend to confirm the order status
Configure webhooksSet up webhooks for real-time payment notifications
Flexible JSON parsingDo not fail on unknown fields — new fields may be added without notice
Avoid hardcodingDo not hardcode field values, response structures, or error codes
TLS 1.2+All API calls must use TLS 1.2 or higher
Sanity testingTest the complete flow on UAT before going live
New chat
Responses are generated using AI and may contain mistakes.
Hi! I'm Pine, your AI developer assistant. Ask me anything about Pine Labs APIs, integrations, or troubleshooting.

Tip: you can create a new chat with + E