m2pfintech
Click to Pay

Integration Guide

End-to-end integration flow, feature toggle configuration, polling strategy, and error handling for Click to Pay.

End-to-End Integration Flow

Register the customer on M2P

Use the standard registration APIs to create the customer and assign a kit:

POST /Yappay/registration-manager/v4/register

If CTP is enabled with ALL scope for your tenant, CTP enrollment is triggered automatically after successful registration — you can skip to step 4.

Assign a kit (if not done during registration)

If the card was not assigned during registration, use:

POST /Yappay/business-entity-manager/addCard

Obtain explicit consent from the cardholder, then call:

POST /Yappay/click-to-pay/v1/registerEntityAndKit

with the entityId, kitNo, and consent object.

Poll for enrollment status

Use the returned requestTraceId to track the async operation:

POST /Yappay/click-to-pay/v1/fetchRequestStatus

Verify enrollment

Once status is SUCCESS, confirm via:

POST /Yappay/click-to-pay/v1/fetchEntityDetails

or check the ctpStatus field in existing APIs:

GET /Yappay/business-entity-manager/fetchEntityByEntityid/{entityId}

Feature Toggle Configuration

CTP is controlled via the BUSINESSCUSTOMFIELD table with the key click.to.pay.enable.

Toggle Formats

ValueBehavior
Y|ALLCTP enabled for all entities. Auto-enrollment triggers on v3/v4 registration
Y|entityId1|entityId2|...CTP enabled only for listed entity IDs
NCTP disabled for the tenant

Configuration Properties

All CTP configuration is stored in BUSINESSCUSTOMFIELD for each tenant:

Property KeyDescriptionExample
click.to.pay.enableFeature toggleY|ALL
default.country.code.clicktopayDefault country for ISO code conversionIndia
ctp.consent.versionConsent version sent to Visa1.0
ctp.default.localeDefault locale tagen-US
ctp.base.saas.urlBase URL of the CTP SaaS APIhttps://ctp-saas.internal/api
ctp.callback.urlWebhook callback URL for SaaShttps://api.m2p.com/Yappay/click-to-pay/v1/clickToPayResponse
ctp.default.stateDefault state codeDL

These configuration values are managed by M2P operations. Contact your account manager to configure CTP for your tenant.


Auto-Enrollment on Registration

When CTP is enabled with ALL scope (Y|ALL), the platform automatically triggers CTP enrollment after a successful customer registration via v3/register or v4/register.

This means for Y|ALL tenants, clients do not need to explicitly call the CTP registration API — enrollment happens automatically as part of the registration flow.


Auto-Sync on Profile Updates

When a customer's profile is updated via POST /business-entity-manager/updateentity, the platform automatically syncs relevant changes to the Visa CTP network:

Updated Field(s)CTP Action
First name, last name, email, contact numberCTP_UPDATE_ENTITY — syncs customer data to Visa
Address fields (address1, city, state, country, pincode)CTP_UPDATE_KIT — syncs payment instrument data to Visa

These syncs happen after the database transaction commits (using Spring @TransactionalEventListener with AFTER_COMMIT phase) and are non-blocking.


Polling Strategy

For operations where webhook delivery is not configured or as a fallback, use fetchRequestStatus polling:

Initial poll:     After 5 seconds
Retry interval:   Every 10 seconds
Max attempts:     12 (total ~2 minutes)
Fallback:         If still IN_PROGRESS after 2 minutes, retry after 5 minutes

Internal Retry Behavior

The fetchRequestStatus endpoint internally queries the SaaS /status endpoint with a built-in retry mechanism:

  • 4 retry attempts with 1-second delay between each
  • If the SaaS reports a completed status that hasn't been processed via webhook, the platform automatically processes it (updates CTP records and sends notifications)

The webhook is the primary status delivery mechanism. Polling via fetchRequestStatus should be used as a fallback or for manual status checks.


Error Handling

Common Error Scenarios

ScenarioError CodeResolution
Entity not registered on M2PY109 / customer.id.invalidRegister the customer via v3/v4 registration API first
Kit not assigned to entityY2271 / kit.not.assignedAssign the kit via addCard API
CTP not enabled for tenantY4038 / click.to.pay.errorContact M2P operations to enable CTP
Entity not registered on CTP (for addKit)Y4038Use registerEntityAndKit first to enroll the entity
Entity not ACTIVE on CTP (for remove)Y4038Entity must be in ACTIVE state to remove
Kit not ACTIVE on CTP (for removeKit)Y4038Kit must be in ACTIVE state to remove
Request Trace ID not found500Verify the requestTraceId was returned by a CTP API
SaaS API failureY4038CTP SaaS service may be temporarily unavailable — retry

Error Response Format

All CTP errors follow the standard M2P response envelope:

{
    "result": null,
    "exception": {
        "detailMessage": "Human-readable error description",
        "cause": null,
        "shortMessage": "Short error summary",
        "languageCode": "en",
        "errorCode": "Y4038",
        "code": "click.to.pay.error",
        "networkHttpStatusCode": null
    },
    "pagination": null
}

Webhook Failure Handling

If a webhook callback indicates failure:

  1. RequestTraceID status is updated to FAILED
  2. CTP entity/kit statuses remain unchanged (stay in REGISTRATION_IN_PROGRESS or REMOVAL_IN_PROGRESS)
  3. A failure notification is sent to the Message Queue queue with error details
  4. The operation can be retried by calling the original API again

Testing Checklist

Use this checklist to validate your CTP integration in the SIT environment:

  • Customer registration creates entity successfully
  • Kit is assigned to the entity
  • registerEntityAndKit returns requestTraceId and event type
  • fetchRequestStatus shows IN_PROGRESSSUCCESS progression
  • fetchEntityDetails returns customer and payment instrument info with ACTIVE status
  • addKit enrolls additional cards successfully
  • removeKit removes a specific card (status → REMOVED)
  • removeEntity removes customer and all cards
  • fetchEntityByEntityid shows ctpStatus field at entity and kit levels
  • getDetailsByKitNo shows ctpStatus and ctpPaymentInstrumentId fields
  • Customer profile update triggers automatic CTP sync
  • Error scenarios return appropriate error codes

Frequently Asked Questions

Q: Can I enroll a customer in CTP without their explicit consent? No. Visa requires documented cardholder consent before CTP enrollment. The consent object is mandatory in the registerEntityAndKit request.

Q: What happens if the SaaS webhook never arrives? Use the fetchRequestStatus API to poll for the result. The status endpoint has built-in retry logic and will process the result if available from the SaaS layer.

Q: Can a customer be re-enrolled after removal? Yes. After an entity is removed (REMOVED status), you can call registerEntityAndKit again to re-enroll them.

Q: Does card replacement affect CTP enrollment? Yes. When a card is replaced via replaceCard, the new kit needs to be separately enrolled in CTP via addKit. The old kit's CTP enrollment is not automatically transferred.

Q: Is CTP enrollment preserved when a card is blocked? Card blocking via block may trigger a CTP status update depending on the block type. Check the ctpStatus after blocking to confirm the current state.

On this page