-
Notifications
You must be signed in to change notification settings - Fork 11
feat(connector): Phonepe upi cc/cl response handling #437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| if let Some(instrument_response) = &data.instrument_response { | ||
| // Detect UPI mode from instrument response | ||
| let upi_mode = | ||
| determine_upi_mode(instrument_response, data.response_code.as_ref()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we also need this for AuthZ flow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not needed
|
|
||
| // Additional payment method data for UPI payments | ||
| message UpiConnectorResponse { | ||
| optional string upi_mode = 1; // UPI mode detected from connector (e.g., "UPICC", "UPICL", "UPI_ACCOUNT") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since this is UPI_SOURCE, use enum here
| // Success but no instrument response | ||
| // Success but no instrument response - try fallback detection from response_code | ||
| let upi_mode = data.response_code.as_ref().and_then(|code| { | ||
| if code == "CREDIT_ACCOUNT_NOT_ALLOWED_FOR_SENDER" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use consts for all these hardcoded values
| /// Extracts UPI mode from sync response payment instrument | ||
| fn extract_upi_mode_from_sync_data(sync_data: &PhonepeSyncResponseData) -> Option<String> { | ||
| // Try to parse payment_instrument JSON to extract fields | ||
| if let Some(payment_instrument) = sync_data.payment_instrument.as_ref() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change payment_instrument from Option<serde_json::Value> to a struct for better handling
| } | ||
| } | ||
|
|
||
| // Fallback: check top-level fields in sync response |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use determine_upi_mode instead
| fn determine_upi_mode( | ||
| instrument_response: &PhonepeInstrumentResponse, | ||
| response_code: Option<&String>, | ||
| ) -> Option<String> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use UpiSource instead of String
Description
Added UPI Credit Card (UPI_CC) and UPI Credit Line (UPI_CL) detection from PhonePe connector responses, and sending the upi_source back in payment sync response in
additional_payment_method_connector_responseMotivation and Context
Additional Changes
How did you test it?
Hyperswitch v2:
Create + confirm - Request
Response :
PSync - Request:
{
"id": "12345_pay_019bdf693bc779709cc585df6975606e",
"status": "succeeded",
"amount": {
"order_amount": 1000,
"currency": "INR",
"shipping_cost": null,
"order_tax_amount": null,
"external_tax_calculation": "skip",
"surcharge_calculation": "skip",
"surcharge_amount": null,
"tax_on_surcharge": null,
"net_amount": 1000,
"amount_to_capture": null,
"amount_capturable": 0,
"amount_captured": 1000
},
"customer_id": null,
"processor_merchant_id": "irctc1768908514_ni3gUbBR6GcqHdk0JBVa",
"initiator": null,
"connector": "phonepe",
"created": "2026-01-21T07:16:14.411Z",
"modified_at": "2026-01-21T07:17:06.773Z",
"payment_method_data": {
"billing": {
"address": {
"city": "San Francisco",
"country": "IN",
"line1": "123 Main St",
"line2": "Apt 4B",
"line3": "Building C",
"zip": "94102",
"state": "CA",
"first_name": "John",
"last_name": "Doe",
"origin_zip": null
},
"phone": {
"number": "9876543210",
"country_code": "+91"
},
"email": "test@juspay.in"
}
},
"payment_method_type": "upi",
"payment_method_subtype": "upi_intent",
"connector_transaction_id": null,
"connector_reference_id": "CREDIT_LINE:1764438444",
"merchant_connector_id": null,
"browser_info": null,
"error": null,
"shipping": null,
"billing": null,
"attempts": null,
"connector_token_details": null,
"payment_method_id": null,
"next_action": null,
"return_url": "https://google.com/success",
"authentication_type": null,
"authentication_type_applied": null,
"is_iframe_redirection_enabled": null,
"merchant_reference_id": "razorpayirctc1768979774",
"raw_connector_response": "{"success":true,"code":"PAYMENT_SUCCESS","message":"Your payment is successful.","data":{"merchantId":"IRCTCUAT","merchantTransactionId":"CREDIT_LINE:1764438444","transactionId":"T2601211246149849246869","amount":1000,"state":"COMPLETED","responseCode":"SUCCESS","paymentInstrument":{"type":"UPI","utr":"206378866112","upiTransactionId":"AXLd8ee55a8fd50452da92639907560b6cd","maskedAccountNumber":"XXXXXXXXXXXX0125","bankId":"HDFC","accountHolderName":"Rajesh Kumar","cardNetwork":null,"accountType":null,"upiCreditLine":true},"metaInfo":null,"feesContext":{"amount":20}}}",
"feature_metadata": null,
"metadata": {
"_notes_91_txn_uuid_93": "12345razorpayirctc1762435588",
"_notes_91_transaction_id_93": "razorpayirctc1762435588"
}
} ```