feat(connector): [PayJustNow In-Store] Implement PayJustNow Payment Method#10745
feat(connector): [PayJustNow In-Store] Implement PayJustNow Payment Method#10745likhinbopanna merged 9 commits intomainfrom
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #10745 +/- ##
=======================================
Coverage ? 6.40%
=======================================
Files ? 1267
Lines ? 317815
Branches ? 0
=======================================
Hits ? 20348
Misses ? 297467
Partials ? 0 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| reason: response.reason, | ||
| code: res.status_code.to_string(), | ||
| message: response.error.unwrap_or(error_message.to_string()), | ||
| reason: String::from_utf8(res.response.to_vec()) |
There was a problem hiding this comment.
Reason will contain the entire response. Is this expected ?
There was a problem hiding this comment.
Populating it with response.error instead.
| item: ResponseRouterData<F, PayjustnowinstorePaymentsResponse, T, PaymentsResponseData>, | ||
| ) -> Result<Self, Self::Error> { | ||
| let redirection_data = url::Url::parse(&item.response.scan_url.clone()) | ||
| .ok() |
There was a problem hiding this comment.
Changing the type of scan_url to url::Url to avoid parsing.
| #[derive(Debug, Clone, Serialize, Deserialize)] | ||
| pub struct PayjustnowinstoreSyncResponse { | ||
| merchant_reference: String, | ||
| token: String, |
There was a problem hiding this comment.
Not required as it's connector_transaction_id.
| let status = enums::AttemptStatus::from(item.response.payment_status); | ||
| let redirection_data = item.response.scan_url.and_then(|url_string| { | ||
| url::Url::parse(&url_string) | ||
| .ok() |
There was a problem hiding this comment.
Changing the type of scan_url to url::Url to avoid parsing.
| .map(|url| RedirectForm::from((url, Method::Get))) | ||
| }); | ||
|
|
||
| let response = if status == enums::AttemptStatus::Failure { |
There was a problem hiding this comment.
Use is_payment_failure from utils
| }) | ||
| } else { | ||
| let connector_metadata = | ||
| Some(serde_json::json!({"merchant_reference": item.response.merchant_reference})); |
There was a problem hiding this comment.
Create a struct and convert it into connector_metadata
| pub amount: MinorUnit, | ||
| request_id: String, | ||
| merchant_reference: String, | ||
| token: String, |
There was a problem hiding this comment.
Make this field a secret
There was a problem hiding this comment.
Not required as it's connector_transaction_id.
| [payjustnowinstore] | ||
| api_key="Merchant Terminal Id" No newline at end of file | ||
| api_key = "Merchant API Key" | ||
| key1 = "Merchant Terminal Id" No newline at end of file |
There was a problem hiding this comment.
Should we add [payjustnowinstore.pay_later]] here
| PayjustnowinstorePaymentStatus::Succeeded => Self::Charged, | ||
| PayjustnowinstorePaymentStatus::Failed => Self::Failure, | ||
| PayjustnowinstorePaymentStatus::Processing => Self::Authorizing, | ||
| PayjustnowinstorePaymentStatus::Pending => Self::AuthenticationPending, |
There was a problem hiding this comment.
Is pending always authentication pending
There was a problem hiding this comment.
Yes, as the response status is sync.
Type of Change
Closes this issue
Description
Implemented PayJustNow Payment Method in PayJustNow In-Store connector.
Flows Implemented:
Note: Refund statuses are in sync; a refund is either successful or failed. So RSync is not required here.
Additional Changes
Motivation and Context
How did you test it?
Postman Tests
Request:
Response:
{ "payment_id": "pay_PeCq56nzxQJIPHiop8Dc", "merchant_id": "merchant_1766153181", "status": "requires_customer_action", "amount": 2, "net_amount": 2, "shipping_cost": null, "amount_capturable": 2, "amount_received": null, "connector": "payjustnowinstore", "client_secret": "pay_PeCq56nzxQJIPHiop8Dc_secret_StGUIA8WvMomJ0VrXQeg", "created": "2025-12-19T14:07:27.901Z", "modified_at": "2025-12-19T14:07:30.070Z", "currency": "ZAR", "customer_id": "customer123", "customer": { "id": "customer123", "name": "John Doe", "email": "customer@gmail.com", "phone": "9999999999", "phone_country_code": "+1" }, "description": "Its my first payment request", "refunds": null, "disputes": null, "mandate_id": null, "mandate_data": null, "setup_future_usage": null, "off_session": null, "capture_on": null, "capture_method": "automatic", "payment_method": "pay_later", "payment_method_data": { "pay_later": { "klarna_sdk": null }, "billing": null }, "payment_token": null, "shipping": { "address": { "city": "San Fransico", "country": "ZA", "line1": "1467", "line2": "Harrison Street", "line3": "Harrison Street", "zip": "94122", "state": "California", "first_name": "joseph", "last_name": "Doe", "origin_zip": null }, "phone": { "number": "8056594427", "country_code": "+91" }, "email": "guest@example.com" }, "billing": { "address": { "city": "San Fransico", "country": "ZA", "line1": "1467", "line2": "Harrison Street", "line3": "Harrison Street", "zip": "94122", "state": "California", "first_name": "joseph", "last_name": "Doe", "origin_zip": null }, "phone": { "number": "8056594427", "country_code": "+91" }, "email": "guest@example.com" }, "order_details": [ { "sku": null, "upc": null, "brand": null, "amount": 2, "category": null, "quantity": 1, "tax_rate": null, "product_id": "", "description": null, "product_name": "Apple iphone 15", "product_type": null, "sub_category": null, "total_amount": null, "commodity_code": null, "unit_of_measure": null, "product_img_link": null, "product_tax_code": null, "total_tax_amount": null, "requires_shipping": null, "unit_discount_amount": null } ], "email": "customer@gmail.com", "name": "John Doe", "phone": "9999999999", "return_url": "https://www.google.com/", "authentication_type": "three_ds", "statement_descriptor_name": "joseph", "statement_descriptor_suffix": "JS", "next_action": { "type": "redirect_to_url", "redirect_to_url": "http://localhost:8080/payments/redirect/pay_PeCq56nzxQJIPHiop8Dc/merchant_1766153181/pay_PeCq56nzxQJIPHiop8Dc_1" }, "cancellation_reason": null, "error_code": null, "error_message": null, "unified_code": null, "unified_message": null, "payment_experience": null, "payment_method_type": "payjustnow", "connector_label": null, "business_country": null, "business_label": "default", "business_sub_label": null, "allowed_payment_method_types": null, "manual_retry_allowed": null, "connector_transaction_id": "96d832061e8924dcab8229a66d902d48", "frm_message": null, "metadata": { "udf1": "value1", "login_date": "2019-09-10T10:11:12Z", "new_customer": "true" }, "connector_metadata": null, "feature_metadata": { "redirect_response": null, "search_tags": null, "apple_pay_recurring_details": null, "gateway_system": "direct" }, "reference_id": null, "payment_link": null, "profile_id": "pro_bRTlaNNrrUwnrlVOUHVE", "surcharge_details": null, "attempt_count": 1, "merchant_decision": null, "merchant_connector_id": "mca_wBeYnCk4IkXpTah0eHjR", "incremental_authorization_allowed": false, "authorization_count": null, "incremental_authorizations": null, "external_authentication_details": null, "external_3ds_authentication_attempted": false, "expires_on": "2025-12-19T14:22:27.901Z", "fingerprint": null, "browser_info": { "language": "nl-NL", "time_zone": 0, "ip_address": "128.0.0.1", "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36", "color_depth": 24, "java_enabled": true, "screen_width": 1536, "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "screen_height": 723, "java_script_enabled": true }, "payment_channel": null, "payment_method_id": null, "network_transaction_id": null, "payment_method_status": null, "updated": "2025-12-19T14:07:30.070Z", "split_payments": null, "frm_metadata": null, "extended_authorization_applied": null, "extended_authorization_last_applied_at": null, "request_extended_authorization": null, "capture_before": null, "merchant_order_reference_id": null, "order_tax_amount": null, "connector_mandate_id": null, "card_discovery": null, "force_3ds_challenge": false, "force_3ds_challenge_trigger": false, "issuer_error_code": null, "issuer_error_message": null, "is_iframe_redirection_enabled": null, "whole_connector_response": null, "enable_partial_authorization": null, "enable_overcapture": null, "is_overcapture_enabled": null, "network_details": null, "is_stored_credential": null, "mit_category": null, "billing_descriptor": null, "tokenization": null, "partner_merchant_identifier_details": null, "payment_method_tokenization_details": null }Request:
Response:
{ "payment_id": "pay_PeCq56nzxQJIPHiop8Dc", "merchant_id": "merchant_1766153181", "status": "succeeded", "amount": 2, "net_amount": 2, "shipping_cost": null, "amount_capturable": 0, "amount_received": 2, "connector": "payjustnowinstore", "client_secret": "pay_PeCq56nzxQJIPHiop8Dc_secret_StGUIA8WvMomJ0VrXQeg", "created": "2025-12-19T14:07:27.901Z", "modified_at": "2025-12-19T14:22:52.542Z", "currency": "ZAR", "customer_id": "customer123", "customer": { "id": "customer123", "name": "John Doe", "email": "customer@gmail.com", "phone": "9999999999", "phone_country_code": "+1" }, "description": "Its my first payment request", "refunds": null, "disputes": null, "attempts": [ { "attempt_id": "pay_PeCq56nzxQJIPHiop8Dc_1", "status": "authentication_pending", "amount": 2, "order_tax_amount": null, "currency": "ZAR", "connector": "payjustnowinstore", "error_message": null, "payment_method": "pay_later", "connector_transaction_id": "96d832061e8924dcab8229a66d902d48", "capture_method": "automatic", "authentication_type": "three_ds", "created_at": "2025-12-19T14:07:27.902Z", "modified_at": "2025-12-19T14:18:41.226Z", "cancellation_reason": null, "mandate_id": null, "error_code": null, "payment_token": null, "connector_metadata": null, "payment_experience": null, "payment_method_type": "payjustnow", "reference_id": null, "unified_code": null, "unified_message": null, "client_source": null, "client_version": null } ], "mandate_id": null, "mandate_data": null, "setup_future_usage": null, "off_session": null, "capture_on": null, "capture_method": "automatic", "payment_method": "pay_later", "payment_method_data": { "pay_later": { "klarna_sdk": null }, "billing": null }, "payment_token": null, "shipping": { "address": { "city": "San Fransico", "country": "ZA", "line1": "1467", "line2": "Harrison Street", "line3": "Harrison Street", "zip": "94122", "state": "California", "first_name": "joseph", "last_name": "Doe", "origin_zip": null }, "phone": { "number": "8056594427", "country_code": "+91" }, "email": "guest@example.com" }, "billing": { "address": { "city": "San Fransico", "country": "ZA", "line1": "1467", "line2": "Harrison Street", "line3": "Harrison Street", "zip": "94122", "state": "California", "first_name": "joseph", "last_name": "Doe", "origin_zip": null }, "phone": { "number": "8056594427", "country_code": "+91" }, "email": "guest@example.com" }, "order_details": [ { "sku": null, "upc": null, "brand": null, "amount": 2, "category": null, "quantity": 1, "tax_rate": null, "product_id": "", "description": null, "product_name": "Apple iphone 15", "product_type": null, "sub_category": null, "total_amount": null, "commodity_code": null, "unit_of_measure": null, "product_img_link": null, "product_tax_code": null, "total_tax_amount": null, "requires_shipping": null, "unit_discount_amount": null } ], "email": "customer@gmail.com", "name": "John Doe", "phone": "9999999999", "return_url": "https://www.google.com/", "authentication_type": "three_ds", "statement_descriptor_name": "joseph", "statement_descriptor_suffix": "JS", "next_action": null, "cancellation_reason": null, "error_code": null, "error_message": null, "unified_code": null, "unified_message": null, "payment_experience": null, "payment_method_type": "payjustnow", "connector_label": null, "business_country": null, "business_label": "default", "business_sub_label": null, "allowed_payment_method_types": null, "manual_retry_allowed": null, "connector_transaction_id": "96d832061e8924dcab8229a66d902d48", "frm_message": null, "metadata": { "udf1": "value1", "login_date": "2019-09-10T10:11:12Z", "new_customer": "true" }, "connector_metadata": null, "feature_metadata": { "redirect_response": null, "search_tags": null, "apple_pay_recurring_details": null, "gateway_system": "direct" }, "reference_id": null, "payment_link": null, "profile_id": "pro_bRTlaNNrrUwnrlVOUHVE", "surcharge_details": null, "attempt_count": 1, "merchant_decision": null, "merchant_connector_id": "mca_wBeYnCk4IkXpTah0eHjR", "incremental_authorization_allowed": false, "authorization_count": null, "incremental_authorizations": null, "external_authentication_details": null, "external_3ds_authentication_attempted": false, "expires_on": "2025-12-19T14:22:27.901Z", "fingerprint": null, "browser_info": { "language": "nl-NL", "time_zone": 0, "ip_address": "128.0.0.1", "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36", "color_depth": 24, "java_enabled": true, "screen_width": 1536, "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "screen_height": 723, "java_script_enabled": true }, "payment_channel": null, "payment_method_id": null, "network_transaction_id": null, "payment_method_status": null, "updated": "2025-12-19T14:22:52.542Z", "split_payments": null, "frm_metadata": null, "extended_authorization_applied": null, "extended_authorization_last_applied_at": null, "request_extended_authorization": null, "capture_before": null, "merchant_order_reference_id": null, "order_tax_amount": null, "connector_mandate_id": null, "card_discovery": null, "force_3ds_challenge": false, "force_3ds_challenge_trigger": false, "issuer_error_code": null, "issuer_error_message": null, "is_iframe_redirection_enabled": null, "whole_connector_response": null, "enable_partial_authorization": null, "enable_overcapture": null, "is_overcapture_enabled": null, "network_details": null, "is_stored_credential": null, "mit_category": null, "billing_descriptor": null, "tokenization": null, "partner_merchant_identifier_details": null, "payment_method_tokenization_details": null }Request:
Response:
{ "refund_id": "ref_lsEnyw1ipgo96D2DHzyv", "payment_id": "pay_PeCq56nzxQJIPHiop8Dc", "amount": 1, "currency": "ZAR", "status": "succeeded", "reason": "CUSTOMER REQUEST", "metadata": { "udf1": "value1", "new_customer": "true", "login_date": "2019-09-10T10:11:12Z" }, "error_message": null, "error_code": null, "unified_code": null, "unified_message": null, "created_at": "2025-12-19T14:22:59.040Z", "updated_at": "2025-12-19T14:23:03.109Z", "connector": "payjustnowinstore", "profile_id": "pro_bRTlaNNrrUwnrlVOUHVE", "merchant_connector_id": "mca_wBeYnCk4IkXpTah0eHjR", "split_refunds": null, "issuer_error_code": null, "issuer_error_message": null, "raw_connector_response": null, }Dashboard Screenshots:
Checklist
cargo +nightly fmt --allcargo clippy