Skip to content

Conversation

@Anurag-05-prog
Copy link
Contributor

@Anurag-05-prog Anurag-05-prog commented Sep 21, 2025

Description

Added cards flow through peachpayments connector.

Note: Refunds and RSync has not been implemented.

Motivation and Context

Additional Changes

  • This PR modifies the API contract
  • This PR modifies application configuration/environment variables

How did you test it?

gRPC curls:

Authorize Response:

{
  "transactionId": {
    "id": "fb0cb172-e73d-4dad-b3ef-4400fa1468d9"
  },
  "status": "AUTHORIZED",
  "responseRefId": {
    "id": "fb0cb172-e73d-4dad-b3ef-4400fa1468d9"
  },
  "statusCode": 200,
  "responseHeaders": {
    "cache-control": "no-cache, no-store, max-age=0, must-revalidate",
    "cf-cache-status": "DYNAMIC",
    "cf-ray": "98286040add2c266-BOM",
    "connection": "keep-alive",
    "content-type": "application/json",
    "date": "Sun, 21 Sep 2025 09:01:07 GMT",
    "expires": "0",
    "pragma": "no-cache",
    "server": "cloudflare",
    "strict-transport-security": "max-age=31536000 ; includeSubDomains",
    "transfer-encoding": "chunked",
    "vary": "Origin,Access-Control-Request-Method,Access-Control-Request-Headers",
    "x-content-type-options": "nosniff",
    "x-correlation-id": "592ca9be-8ecd-4fa4-9488-83c668d84d05",
    "x-envoy-upstream-service-time": "907",
    "x-frame-options": "DENY",
    "x-xss-protection": "0"
  }
}

Capture Response:

{
  "transactionId": {
    "id": "fb0cb172-e73d-4dad-b3ef-4400fa1468d9"
  },
  "status": "CHARGED",
  "responseRefId": {
    "id": "fb0cb172-e73d-4dad-b3ef-4400fa1468d9"
  },
  "statusCode": 200,
  "responseHeaders": {
    "cache-control": "no-cache, no-store, max-age=0, must-revalidate",
    "cf-cache-status": "DYNAMIC",
    "cf-ray": "982866301a6085b7-BOM",
    "connection": "keep-alive",
    "content-type": "application/json",
    "date": "Sun, 21 Sep 2025 09:05:10 GMT",
    "expires": "0",
    "pragma": "no-cache",
    "server": "cloudflare",
    "strict-transport-security": "max-age=31536000 ; includeSubDomains",
    "transfer-encoding": "chunked",
    "vary": "Origin,Access-Control-Request-Method,Access-Control-Request-Headers",
    "x-content-type-options": "nosniff",
    "x-correlation-id": "b7000905-806d-44d7-be40-110aeb593e9f",
    "x-envoy-upstream-service-time": "914",
    "x-frame-options": "DENY",
    "x-xss-protection": "0"
  }
}

PSync Response:

{
  "transactionId": {
    "id": "fb0cb172-e73d-4dad-b3ef-4400fa1468d9"
  },
  "status": "CHARGED",
  "statusCode": 200,
  "responseHeaders": {
    "cache-control": "no-cache, no-store, max-age=0, must-revalidate",
    "cf-cache-status": "DYNAMIC",
    "cf-ray": "982867e83b3685b7-BOM",
    "connection": "keep-alive",
    "content-type": "application/json",
    "date": "Sun, 21 Sep 2025 09:06:19 GMT",
    "expires": "0",
    "pragma": "no-cache",
    "server": "cloudflare",
    "strict-transport-security": "max-age=31536000 ; includeSubDomains",
    "transfer-encoding": "chunked",
    "vary": "Origin,Access-Control-Request-Method,Access-Control-Request-Headers",
    "x-content-type-options": "nosniff",
    "x-correlation-id": "3372434a-f08e-4195-948b-2995e5b1acfb",
    "x-envoy-upstream-service-time": "18",
    "x-frame-options": "DENY",
    "x-xss-protection": "0"
  }
}

Void Response:

{
  "transactionId": {
    "noResponseIdMarker": {}
  },
  "status": "VOIDED",
  "errorCode": "00",
  "errorMessage": "00",
  "responseRefId": {
    "id": "b420e2ea-bc5a-44cc-a309-df9162bc5112"
  },
  "statusCode": 200,
  "responseHeaders": {
    "cache-control": "no-cache, no-store, max-age=0, must-revalidate",
    "cf-cache-status": "DYNAMIC",
    "cf-ray": "98286b16ac4d85b7-BOM",
    "connection": "keep-alive",
    "content-type": "application/json",
    "date": "Sun, 21 Sep 2025 09:08:30 GMT",
    "expires": "0",
    "pragma": "no-cache",
    "server": "cloudflare",
    "strict-transport-security": "max-age=31536000 ; includeSubDomains",
    "transfer-encoding": "chunked",
    "vary": "Origin,Access-Control-Request-Method,Access-Control-Request-Headers",
    "x-content-type-options": "nosniff",
    "x-correlation-id": "c5b2b3af-428d-4b6d-bc69-7ad2a306a0b1",
    "x-envoy-upstream-service-time": "897",
    "x-frame-options": "DENY",
    "x-xss-protection": "0"
  }
}

Automated Test

Screenshot 2025-09-23 at 11 33 46 PM

Testing through Hyperswitch

Payments - Create

Request:

curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: ••••••' \
--data-raw '{
    "amount": 1000,
    "currency": "USD",
    "confirm": true,
    "capture_method": "manual",
    "customer_id": "StripeCustomer",
    "email": "[email protected]",
    "name": "John Doe",
    "phone": "999999999",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://duck.com",
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_method_data": {
        "card": {
            "card_number": "4242424242424242",
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "card_cvc": "123",
            "card_network":  "VISA"
        }
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "PiX"
        }
    },
    "metadata": {
        "connector_meta_data": "{\"client_merchant_reference_id\":\"CLIENT MERCHANT REFERENCE ID\",\"name\":\"NAME\",\"mcc\":\"MCC\",\"phone\":\"27726599258\",\"email\":\"[email protected]\",\"mobile\":\"27726599258\",\"address\":\"35 Brickfield Rd\",\"city\":\"Cape Town\",\"postalCode\":\"7925\",\"regionCode\":\"WC\",\"merchantType\":\"MERCHANT TYPE\",\"websiteUrl\":\"example.com\",\"route\":\"ROUTE\",\"mid\":\"MID\",\"tid\":\"TID\",\"subMid\":\"SUBMID\",\"visaPaymentFacilitatorId\":\"VISAPAYMENTFACILITATORID\",\"masterCardPaymentFacilitatorId\":\"MASTERCARDPAYMENTFACILITATORID\"}"
    },
    "browser_info": {
        "color_depth": 24,
        "java_enabled": true,
        "java_script_enabled": true,
        "language": "en-US",
        "screen_height": 848,
        "screen_width": 1312,
        "time_zone": -330,
        "ip_address": "65.1.52.128",
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3.1 Safari/605.1.15",
        "os_type": "macOS",
        "os_version": "10.15.7",
        "device_model": "Macintosh",
        "accept_language": "en"
    }
}'

Response:

{
    "payment_id": "pay_2POhxvMBaEDy88vz9cwX",
    "merchant_id": "merchant_1757610148",
    "status": "requires_capture",
    "amount": 1000,
    "net_amount": 1000,
    "shipping_cost": null,
    "amount_capturable": 1000,
    "amount_received": null,
    "connector": "peachpayments",
    "client_secret": "pay_2POhxvMBaEDy88vz9cwX_secret_1BIiQY7RkIeBsyqU7YRF",
    "created": "2025-09-11T17:13:57.373Z",
    "currency": "USD",
    "customer_id": "StripeCustomer",
    "customer": {
        "id": "StripeCustomer",
        "name": "John Doe",
        "email": "[email protected]",
        "phone": "999999999",
        "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": "manual",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "4242",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "424242",
            "card_extended_bin": null,
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "PiX",
            "last_name": null,
            "origin_zip": null
        },
        "phone": null,
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "joseph",
            "last_name": "Doe",
            "origin_zip": null
        },
        "phone": null,
        "email": null
    },
    "order_details": null,
    "email": "[email protected]",
    "name": "John Doe",
    "phone": "999999999",
    "return_url": "https://duck.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "credit",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": {
        "customer_id": "StripeCustomer",
        "created_at": 1757610837,
        "expires": 1757614437,
        "secret": "epk_826cdebaa0dc4fb197d4a229381cff54"
    },
    "manual_retry_allowed": null,
    "connector_transaction_id": "884be477-1865-4f40-b452-ae792e21a6d5",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": {
        "redirect_response": null,
        "search_tags": null,
        "apple_pay_recurring_details": null,
        "gateway_system": "direct"
    },
    "reference_id": "884be477-1865-4f40-b452-ae792e21a6d5",
    "payment_link": null,
    "profile_id": "pro_5BUfDMTQyz5EbHajw6SE",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_ef4ONOxde7RCQQfvhHJJ",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-09-11T17:28:57.373Z",
    "fingerprint": null,
    "browser_info": {
        "os_type": "macOS",
        "language": "en-US",
        "time_zone": -330,
        "ip_address": "65.1.52.128",
        "os_version": "10.15.7",
        "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3.1 Safari/605.1.15",
        "color_depth": 24,
        "device_model": "Macintosh",
        "java_enabled": true,
        "screen_width": 1312,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 848,
        "accept_language": "en",
        "java_script_enabled": true
    },
    "payment_channel": null,
    "payment_method_id": null,
    "network_transaction_id": null,
    "payment_method_status": null,
    "updated": "2025-09-11T17:13:59.291Z",
    "split_payments": null,
    "frm_metadata": null,
    "extended_authorization_applied": null,
    "capture_before": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null,
    "card_discovery": "manual",
    "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
}
Payments - Sync

Request:

curl --location 'http://localhost:8080/payments/pay_2POhxvMBaEDy88vz9cwX?force_sync=true' \
--header 'Accept: application/json' \
--header 'api-key: ••••••'

Response:

{
    "payment_id": "pay_2POhxvMBaEDy88vz9cwX",
    "merchant_id": "merchant_1758699886",
    "status": "requires_capture",
    "amount": 1000,
    "net_amount": 1000,
    "shipping_cost": null,
    "amount_capturable": 1000,
    "amount_received": null,
    "connector": "peachpayments",
    "client_secret": "pay_2POhxvMBaEDy88vz9cwX_secret_1BIiQY7RkIeBsyqU7YRF",
    "created": "2025-09-24T08:16:30.425Z",
    "currency": "USD",
    "customer_id": "StripeCustomer",
    "customer": {
        "id": "StripeCustomer",
        "name": "John Doe",
        "email": "[email protected]",
        "phone": "999999999",
        "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": "manual",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "4242",
            "card_type": "CREDIT",
            "card_network": "Visa",
            "card_issuer": "STRIPE PAYMENTS UK LIMITED",
            "card_issuing_country": "UNITEDKINGDOM",
            "card_isin": "424242",
            "card_extended_bin": null,
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "PiX",
            "last_name": null,
            "origin_zip": null
        },
        "phone": null,
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "joseph",
            "last_name": "Doe",
            "origin_zip": null
        },
        "phone": null,
        "email": null
    },
    "order_details": null,
    "email": "[email protected]",
    "name": "John Doe",
    "phone": "999999999",
    "return_url": "https://duck.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "credit",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": null,
    "connector_transaction_id": "884be477-1865-4f40-b452-ae792e21a6d5",
    "frm_message": null,
    "connector_metadata": null,
    "feature_metadata": {
        "redirect_response": null,
        "search_tags": null,
        "apple_pay_recurring_details": null,
        "gateway_system": "unified_connector_service"
    },
    "reference_id": "202b18f3-e6bf-4ad1-a7e9-a694027fd690",
    "payment_link": null,
    "profile_id": "pro_nnZ5IMgdWpOP8ddtIJ4e",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_iW7xFwi3pgcRvZCWfP63",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-09-24T08:31:30.425Z",
    "fingerprint": null,
    "browser_info": {
        "os_type": "macOS",
        "language": "en-US",
        "time_zone": -330,
        "ip_address": "65.1.52.128",
        "os_version": "10.15.7",
        "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3.1 Safari/605.1.15",
        "color_depth": 24,
        "device_model": "Macintosh",
        "java_enabled": true,
        "screen_width": 1312,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 848,
        "accept_language": "en",
        "java_script_enabled": true
    },
    "payment_channel": null,
    "payment_method_id": null,
    "network_transaction_id": null,
    "payment_method_status": null,
    "updated": "2025-09-24T08:16:48.642Z",
    "split_payments": null,
    "frm_metadata": null,
    "extended_authorization_applied": null,
    "capture_before": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null,
    "card_discovery": "manual",
    "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
}

@Anurag-05-prog Anurag-05-prog self-assigned this Sep 21, 2025
@Anurag-05-prog Anurag-05-prog requested review from a team as code owners September 21, 2025 09:10
@Anurag-05-prog Anurag-05-prog added the coderabbit-ai-review Trigger CodeRabbit review label Sep 21, 2025
@coderabbitai
Copy link

coderabbitai bot commented Sep 21, 2025

📝 Walkthrough

Walkthrough

Adds a new Peachpayments connector: public module and re-export; full connector implementation with transformers, models, trait and integration implementations; config entries for base URLs; domain and gRPC enum updates; factory registration; and gRPC integration tests for authorize/capture/void/sync flows.

Changes

Cohort / File(s) Summary of Changes
Connector exposure & factory
backend/connector-integration/src/connectors.rs, backend/connector-integration/src/types.rs
Introduces pub mod peachpayments and pub use self::peachpayments::Peachpayments; registers ConnectorEnum::Peachpayments => Box::new(Peachpayments::new()) in connector factory and updates connector imports/exports.
Connector implementation
backend/connector-integration/src/connectors/peachpayments.rs
New peachpayments connector: implements ConnectorServiceTrait plus many flow traits (authorize, psync, capture, void, refunds, validation, orders/mandates/repeat, tokens, disputes, webhooks, etc.), macro-driven URL/header helpers, base_url/auth header builders, and ConnectorIntegrationV2 stubs for various flows.
Transformers & models
backend/connector-integration/src/connectors/peachpayments/transformers.rs
Adds request/response models, auth/metadata structs (PeachPaymentsConnectorMetadataObject, PeachpaymentsAuthType), enums (statuses, response codes, failure reasons), PeachpaymentsErrorResponse, many TryFrom/From conversions between router data and Peachpayments payloads/responses, and utility helpers (error extraction, ISO8601 time handling, success mapping).
Domain types & gRPC enum
backend/domain_types/src/connector_types.rs, backend/domain_types/src/types.rs, backend/grpc-api-types/proto/payment.proto
Adds Peachpayments variant to ConnectorEnum, maps gRPC Connector → Peachpayments, adds pub peachpayments: ConnectorParams to Connectors, and adds PEACHPAYMENTS = 95 to the gRPC Connector enum.
Configuration
config/development.toml, config/production.toml, config/sandbox.toml
Adds connectors.peachpayments.base_url entries per environment (development, production, sandbox) with respective base URLs.
Integration tests
backend/grpc-server/tests/peachpayments_payment_flows_test.rs
New gRPC integration tests exercising health, authorize→capture, authorize→void, and sync flows; includes helpers for metadata, timestamps, request construction, transaction ID extraction, and environment-driven connector credentials.

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "feat(connectors): [Peachpayments] Add Cards Flow" directly and clearly summarizes the main change in the changeset. The title explicitly identifies the connector (Peachpayments) and the primary feature being added (cards flow/payment flow), which is accurately reflected in the raw_summary showing implementation of payment authorization, capture, void, and sync flows. The title is concise, uses a conventional format, and a teammate scanning commit history would immediately understand this PR adds card payment support for the Peachpayments connector. The title is not vague, overly broad, or off-topic.
Description Check ✅ Passed The pull request description is clearly related to the changeset. The author explicitly states "Added cards flow through peachpayments connector" which directly describes the primary change documented in the raw_summary, and provides important context by noting that "Refunds and RSync has not been implemented." The description is supported by extensive testing evidence including gRPC curl responses demonstrating working Authorize, Capture, PSync, and Void flows, along with end-to-end Hyperswitch examples. While the description is relatively brief in the opening section, it is not vague or generic—it is specific about what was added and which connector, and the accompanying evidence demonstrates the implementation is complete for the stated scope.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (5)
backend/connector-integration/src/connectors/peachpayments/transformers.rs (2)

430-441: Auth extraction path looks correct; consider deriving Debug/Clone.

If the connector layer logs or clones auth, deriving Debug (with redaction) and Clone on PeachpaymentsAuthType can simplify usage.

-pub struct PeachpaymentsAuthType {
+#[derive(Clone, Debug)]
+pub struct PeachpaymentsAuthType {

309-341: Enforce explicit validation + clearer errors for PeachPayments connector metadata (mid/tid/route).

PeachPaymentsConnectorMetadataObject requires mid and tid (Secret) and has a Route with a default; TryFrom calls utils::to_connector_meta_from_secret(...) which yields a generic InvalidConnectorConfig { config: "metadata" } on deserialize failure. Add explicit runtime checks after deserialization (or improve to_connector_meta_from_secret) to return field-specific errors when mid/tid/route are missing or invalid so callers receive actionable messages.
Location: backend/connector-integration/src/connectors/peachpayments/transformers.rs (struct ~line 238; TryFrom impl ~line 27; conversion call ~line 309).

backend/connector-integration/src/connectors/peachpayments.rs (3)

120-122: Use header-name constants for auth headers.

Centralizes names and reduces typos.

 pub(crate) mod headers {
     pub(crate) const CONTENT_TYPE: &str = "Content-Type";
+    pub(crate) const X_API_KEY: &str = "x-api-key";
+    pub(crate) const X_TENANT_ID: &str = "x-tenant-id";
+    pub(crate) const X_EXI_AUTH_VER: &str = "x-exi-auth-ver";
 }
-        Ok(vec![
-            ("x-api-key".to_string(), auth.api_key.expose().into_masked()),
-            (
-                "x-tenant-id".to_string(),
-                auth.tenant_id.expose().into_masked(),
-            ),
-            ("x-exi-auth-ver".to_string(), "v1".to_string().into_masked()),
-        ])
+        Ok(vec![
+            (headers::X_API_KEY.to_string(), auth.api_key.expose().into_masked()),
+            (headers::X_TENANT_ID.to_string(), auth.tenant_id.expose().into_masked()),
+            (headers::X_EXI_AUTH_VER.to_string(), "v1".to_string().into_masked()),
+        ])

Also applies to: 345-352


508-567: Scope SourceVerification impls to supported flows only.

Trimming Refund/RSync verification impls avoids implying support and reduces compile surface.


186-213: Add E2E tests for authorize/capture/psync/void.

Follow the standard per-connector test pattern.

Would you like a starter test at backend/grpc-server/tests/peachpayments_payment_flows_test.rs covering happy paths and common failures?

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 528e6cf and ff13bb7.

📒 Files selected for processing (8)
  • backend/connector-integration/src/connectors.rs (1 hunks)
  • backend/connector-integration/src/connectors/peachpayments.rs (1 hunks)
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs (1 hunks)
  • backend/connector-integration/src/types.rs (2 hunks)
  • backend/domain_types/src/connector_types.rs (2 hunks)
  • backend/domain_types/src/types.rs (1 hunks)
  • backend/grpc-api-types/proto/payment.proto (1 hunks)
  • config/development.toml (2 hunks)
🧰 Additional context used
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Create end-to-end tests per connector in backend/grpc-server/tests/<connector>_payment_flows_test.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/types.rs : Update convert_connector to map to the new connector

Applied to files:

  • backend/connector-integration/src/connectors.rs
  • backend/domain_types/src/connector_types.rs
  • backend/domain_types/src/types.rs
  • backend/connector-integration/src/types.rs
  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Use macros::create_all_prerequisites! to declare connector struct, supported API flows, optional amount converters, and shared member_functions

Applied to files:

  • backend/connector-integration/src/connectors.rs
  • backend/domain_types/src/connector_types.rs
  • backend/connector-integration/src/types.rs
  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Put connector-specific request/response structs and TryFrom implementations in backend/connector-integration/src/connectors/<connector>/transformers.rs

Applied to files:

  • backend/connector-integration/src/connectors.rs
  • backend/domain_types/src/connector_types.rs
  • backend/connector-integration/src/types.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/domain_types/src/connector_types.rs : Register the new connector in ConnectorEnum

Applied to files:

  • backend/domain_types/src/connector_types.rs
  • backend/domain_types/src/types.rs
  • backend/connector-integration/src/types.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Model connector error variations comprehensively (untagged enums, string errors, empty body cases)

Applied to files:

  • backend/domain_types/src/connector_types.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Create end-to-end tests per connector in backend/grpc-server/tests/<connector>_payment_flows_test.rs

Applied to files:

  • backend/domain_types/src/connector_types.rs
  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Use enums for fields with limited value sets instead of generic strings

Applied to files:

  • backend/domain_types/src/connector_types.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Define precise request and response structs (and error struct) that match the connector’s API formats

Applied to files:

  • backend/domain_types/src/connector_types.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Implement TryFrom<...RouterDataV2...> for connector request types to build outbound payloads

Applied to files:

  • backend/domain_types/src/connector_types.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Provide explicit Not Implemented errors for unsupported payment methods or types when matching over payment_methods/payment_method_types

Applied to files:

  • backend/domain_types/src/connector_types.rs
  • backend/connector-integration/src/types.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Create reusable utility functions for request construction (email, address, return URL, connector transaction IDs)

Applied to files:

  • backend/connector-integration/src/types.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : For every supported flow, use macros::macro_connector_implementation! to wire ConnectorIntegrationV2, specifying defaults, request/response types, headers, URL, and other flow-specific functions

Applied to files:

  • backend/connector-integration/src/types.rs
  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Implement TryFrom<ResponseRouterData<ConnectorResp, RouterDataV2<...>>> for RouterDataV2 to map connector responses, status, and response data

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Use amount framework types (e.g., MinorUnit) instead of primitive integers for amounts in request/response types

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Persist connector identifiers in response handling (connector_transaction_id, reference_id, mandate_id)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Map response_transaction_id and redirect_urls correctly into RouterData fields

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Implement empty marker traits for each supported flow (e.g., PaymentAuthorizeV2, PaymentSyncV2, PaymentCapture)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Write E2E tests covering all supported payment flows, including success and failure paths

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
🧬 Code graph analysis (2)
backend/connector-integration/src/connectors/peachpayments/transformers.rs (4)
backend/domain_types/src/types.rs (1)
  • RawCardNumber (689-689)
backend/connector-integration/src/connectors/macros.rs (1)
  • router_data (94-105)
backend/connector-integration/src/utils.rs (1)
  • to_connector_meta_from_secret (63-88)
sdk/python-grpc-client/src/python_grpc_client/generated/payment_pb2.pyi (1)
  • BodyKey (1651-1657)
backend/connector-integration/src/connectors/peachpayments.rs (3)
backend/connector-integration/src/connectors/macros.rs (2)
  • router_data (94-105)
  • request_body (66-75)
backend/connector-integration/src/connectors/peachpayments/transformers.rs (10)
  • try_from (29-35)
  • try_from (294-381)
  • try_from (400-421)
  • try_from (432-441)
  • try_from (599-656)
  • try_from (675-694)
  • try_from (701-751)
  • try_from (763-815)
  • try_from (827-879)
  • try_from (893-898)
backend/common_utils/src/pii.rs (1)
  • expose (40-42)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (11)
backend/domain_types/src/connector_types.rs (1)

93-93: grpc -> domain mapping for Peachpayments — LGTM.

Mapping aligns with the new proto enum; fallback INVALID_CONNECTOR arm remains intact.

Please regenerate/rebuild gRPC types to ensure codegen includes Peachpayments and no stale artifacts linger.

backend/grpc-api-types/proto/payment.proto (1)

458-458: Connector enum: PEACHPAYMENTS = 94 — verified.
Proto: backend/grpc-api-types/proto/payment.proto — PEACHPAYMENTS = 94 (line 458). Rust: backend/domain_types/src/connector_types.rs — Peachpayments variant and match arm present (lines ~64, ~93). Ordinal fits sequentially; no renumbering required.

backend/connector-integration/src/connectors.rs (1)

59-61: Wiring LGTM.

Module export and re-export are consistent with the project pattern.

config/development.toml (2)

90-91: No-op change acknowledged.

Re-adding x-request-id extraction with identical value is fine.


54-55: Confirm Peachpayments base_url and trailing-slash semantics.

config/development.toml:54 sets peachpayments.base_url = "https://apitest.bankint.ppay.io/v/1" (no trailing slash). The connector builds URLs with format!("{}/transactions", ...), format!("{}/transactions/{}/confirm", ...), and format!("{}/transactions/{}/void", ...) — producing https://apitest.bankint.ppay.io/v/1/transactions, etc. Confirm the sandbox base/path is intended; if upstream expects a different base or a trailing slash, update the config or normalize base_url in code (trim/add trailing slash) to avoid double/missing slashes.

Locations: config/development.toml:54; backend/connector-integration/src/connectors/peachpayments.rs (URL builders ~lines 203–318; base_url fn ~330–336).

backend/connector-integration/src/types.rs (1)

8-10: Factory mapping complete.

Import and match arm for Peachpayments are correct.

Also applies to: 51-52

backend/connector-integration/src/connectors/peachpayments/transformers.rs (2)

691-694: Capture request mapping LGTM.

Amount and currency conversion use MinorUnit; consistent with framework.


884-900: Error mapping OK; preserves code/message.

Mapping ErrorResponse -> PeachpaymentsErrorResponse is straightforward.

backend/domain_types/src/types.rs (1)

113-114: Connector registered; mapping verified — confirm env configs

  • ConnectorEnum includes Peachpayments — backend/domain_types/src/connector_types.rs.
  • convert_connector maps to Peachpayments — backend/connector-integration/src/types.rs.
  • Only config/development.toml defines peachpayments.base_url (config/development.toml); add or confirm base_url entries for staging/production or indicate the alternate config source.
backend/connector-integration/src/connectors/peachpayments.rs (2)

154-169: Add Accept header; do NOT add Idempotency-Key for Peach Payments unless confirmed
Peach Payments' Payments API uses body-based auth and their public docs do not list x-api-key / x-tenant-id / x-exi-auth-ver or an Idempotency-Key/X-Idempotency-Key header. Add the Accept header for interoperability; omit Idempotency-Key unless your tenant/partner docs or Peach support explicitly require it.
File: backend/connector-integration/src/connectors/peachpayments.rs — build_headers (lines 154–169).

Likely an incorrect or invalid review comment.


322-337: Wire-up verified — Peachpayments registered

  • convert_connector maps to Peachpayments — backend/connector-integration/src/types.rs:51.
  • Proto enum contains PEACHPAYMENTS — backend/grpc-api-types/proto/payment.proto:458.
  • Config has peachpayments.base_url — config/development.toml:54.
  • Peachpayments exported in connectors (backend/connector-integration/src/connectors.rs) and referenced throughout peachpayments implementation.
  • Note: RefundSyncV2 and RefundV2 trait impls exist in backend/connector-integration/src/connectors/peachpayments.rs (around lines 64–68) — confirm refunds/rsync are intended to be supported.

Noon,
Braintree,
Volt,
Peachpayments,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 Analysis chain

Add ConnectorEnum::Peachpayments — LGTM.

Enum casing with strum(snake_case) will serialize as "peachpayments" correctly.

Run a quick wiring check across the repo:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# convert_connector mapping
rg -nP 'fn\s+convert_connector' -C3 --type=rust || true
rg -n 'Peachpayments' backend/connector-integration/src/types.rs || echo "Peachpayments mapping missing in connector-integration/src/types.rs"

# connector module presence and export
fd -t f -I 'peachpayments.rs' backend/connector-integration/src/connectors || echo "peachpayments.rs not found under connectors/"
rg -nP 'pub\s+mod\s+peachpayments' backend/connector-integration/src/connectors.rs || echo "pub mod peachpayments not found"

# transformers presence
fd -t f -I 'transformers.rs' backend/connector-integration/src/connectors/peachpayments || echo "transformers.rs not found under connectors/peachpayments"

# e2e tests per learnings
fd -t f -I 'peachpayments*_payment_flows_test.rs' backend/grpc-server/tests || echo "E2E test for Peachpayments flows missing"

# config entries
rg -nC2 'peachpayments' config || echo "peachpayments.* config keys not found"

# explicit NI for unsupported flows (refunds, rsync)
rg -nP 'NotImplemented|NotSupported' backend/connector-integration/src/connectors/peachpayments.rs || echo "Ensure NI errors for unsupported flows."

Length of output: 1308


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Search for E2E tests mentioning peachpayments =="
rg -n --hidden --no-ignore-vcs 'peachpayments' backend/grpc-server/tests || echo "E2E test for Peachpayments flows missing"

echo
echo "== Search for NI markers in peachpayments connector files =="
rg -nP 'NotImplemented|NotSupported|not_implemented|unimplemented' backend/connector-integration/src/connectors/peachpayments* || echo "NI markers missing in peachpayments connector"

echo
echo "== List peachpayments connector files =="
fd -t f -I 'peachpayments*' backend/connector-integration/src/connectors || true

echo
echo "== Peek peachpayments connector file (connectors/peachpayments.rs) =="
if [ -f backend/connector-integration/src/connectors/peachpayments.rs ]; then
  sed -n '1,240p' backend/connector-integration/src/connectors/peachpayments.rs
else
  echo "file not found: backend/connector-integration/src/connectors/peachpayments.rs"
fi

echo
echo "== Peek transformers (connectors/peachpayments/transformers.rs) =="
if [ -f backend/connector-integration/src/connectors/peachpayments/transformers.rs ]; then
  sed -n '1,240p' backend/connector-integration/src/connectors/peachpayments/transformers.rs
else
  echo "file not found: backend/connector-integration/src/connectors/peachpayments/transformers.rs"
fi

echo
echo "== Search for refund / rsync mentions in peachpayments connector =="
rg -nP '\brefund\b|\brsync\b' backend/connector-integration/src/connectors/peachpayments* || echo "No refund/rsync mentions found in peachpayments connector"

Length of output: 17625


Add ConnectorEnum::Peachpayments — LGTM.

strum(snake_case) will serialize as "peachpayments"; convert_connector mapping (backend/connector-integration/src/types.rs), connector module/export, transformers (backend/connector-integration/src/connectors/peachpayments/transformers.rs) and config (config/development.toml) are present.

  • Missing E2E test — add backend/grpc-server/tests/peachpayments_payment_flows_test.rs.
  • Unsupported flows — add explicit NotImplemented/NotSupported for Refund and RSync in backend/connector-integration/src/connectors/peachpayments.rs or transformers.rs (transformers.rs already has NotImplemented for "Payment method" around line ~379).
🤖 Prompt for AI Agents
In backend/domain_types/src/connector_types.rs around line 64,
ConnectorEnum::Peachpayments was added but the PR is missing an E2E test and
explicit unsupported-flow markers; add a new end-to-end test file
backend/grpc-server/tests/peachpayments_payment_flows_test.rs that covers the
expected payment flows, and in
backend/connector-integration/src/connectors/peachpayments.rs (or the
transformers.rs if more appropriate) add explicit NotImplemented/NotSupported
responses for Refund and RSync flows (consistent with existing NotImplemented
usage for payment method), ensuring the connector returns clear unsupported
errors for those flows.

@Anurag-05-prog Anurag-05-prog requested a review from a team as a code owner September 21, 2025 10:52
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
backend/common_utils/src/consts.rs (2)

123-125: Add CONST_SANDBOX for symmetry with existing env constants.

Keeps constants consistent with the Env::Sandbox variant and Display impl.

 pub const CONST_DEVELOPMENT: &str = "development";
 pub const CONST_PRODUCTION: &str = "production";
+pub const CONST_SANDBOX: &str = "sandbox";

25-28: Doc comments for MIN/MAX global id are swapped.

The text does not match the constants; fix the comments.

-/// Minimum length required for a global id
+/// Maximum length allowed for a global id
 pub const MAX_GLOBAL_ID_LENGTH: u8 = 64;
-/// Maximum length allowed for a global id
+/// Minimum length required for a global id
 pub const MIN_GLOBAL_ID_LENGTH: u8 = 32;
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff13bb7 and 669be83.

📒 Files selected for processing (10)
  • backend/common_utils/src/consts.rs (1 hunks)
  • backend/connector-integration/src/connectors.rs (1 hunks)
  • backend/connector-integration/src/types.rs (2 hunks)
  • backend/domain_types/src/connector_types.rs (2 hunks)
  • backend/domain_types/src/types.rs (1 hunks)
  • backend/grpc-api-types/proto/payment.proto (1 hunks)
  • backend/grpc-server/src/main.rs (1 hunks)
  • config/development.toml (2 hunks)
  • config/production.toml (1 hunks)
  • config/sandbox.toml (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • backend/grpc-server/src/main.rs
  • config/production.toml
🚧 Files skipped from review as they are similar to previous changes (5)
  • backend/connector-integration/src/connectors.rs
  • backend/connector-integration/src/types.rs
  • backend/grpc-api-types/proto/payment.proto
  • backend/domain_types/src/types.rs
  • config/development.toml
🧰 Additional context used
🧠 Learnings (15)
📓 Common learnings
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Create end-to-end tests per connector in backend/grpc-server/tests/<connector>_payment_flows_test.rs
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Use macros::create_all_prerequisites! to declare connector struct, supported API flows, optional amount converters, and shared member_functions
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : For every supported flow, use macros::macro_connector_implementation! to wire ConnectorIntegrationV2, specifying defaults, request/response types, headers, URL, and other flow-specific functions
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/types.rs : Update convert_connector to map to the new connector
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Put connector-specific request/response structs and TryFrom implementations in backend/connector-integration/src/connectors/<connector>/transformers.rs
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Implement ConnectorCommon for the connector, including id(), get_currency_unit(), get_auth_header(), base_url(), and build_error_response()
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/types.rs : Update convert_connector to map to the new connector

Applied to files:

  • backend/domain_types/src/connector_types.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/domain_types/src/connector_types.rs : Register the new connector in ConnectorEnum

Applied to files:

  • backend/domain_types/src/connector_types.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Create end-to-end tests per connector in backend/grpc-server/tests/<connector>_payment_flows_test.rs

Applied to files:

  • backend/domain_types/src/connector_types.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Put connector-specific request/response structs and TryFrom implementations in backend/connector-integration/src/connectors/<connector>/transformers.rs

Applied to files:

  • backend/domain_types/src/connector_types.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Model connector error variations comprehensively (untagged enums, string errors, empty body cases)

Applied to files:

  • backend/domain_types/src/connector_types.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Use enums for fields with limited value sets instead of generic strings

Applied to files:

  • backend/domain_types/src/connector_types.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Define precise request and response structs (and error struct) that match the connector’s API formats

Applied to files:

  • backend/domain_types/src/connector_types.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Implement TryFrom<...RouterDataV2...> for connector request types to build outbound payloads

Applied to files:

  • backend/domain_types/src/connector_types.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Write E2E tests covering all supported payment flows, including success and failure paths

Applied to files:

  • backend/domain_types/src/connector_types.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Provide explicit Not Implemented errors for unsupported payment methods or types when matching over payment_methods/payment_method_types

Applied to files:

  • backend/domain_types/src/connector_types.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Implement empty marker traits for each supported flow (e.g., PaymentAuthorizeV2, PaymentSyncV2, PaymentCapture)

Applied to files:

  • backend/domain_types/src/connector_types.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Persist connector identifiers in response handling (connector_transaction_id, reference_id, mandate_id)

Applied to files:

  • backend/domain_types/src/connector_types.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Use macros::create_all_prerequisites! to declare connector struct, supported API flows, optional amount converters, and shared member_functions

Applied to files:

  • backend/domain_types/src/connector_types.rs
📚 Learning: 2025-09-15T06:56:22.535Z
Learnt from: Shubhodip900
PR: juspay/connector-service#172
File: backend/connector-integration/src/connectors/trustpay.rs:747-762
Timestamp: 2025-09-15T06:56:22.535Z
Learning: In Trustpay connector (backend/connector-integration/src/connectors/trustpay.rs), the refund_connector_metadata field has different data formats in different contexts: RSync expects it to be already parsed as JSON Value (accessing directly with .get()), while other refund flows expect it to be a JSON string that needs serde_json::from_str() parsing. The extract_payment_method_from_refund_metadata helper is designed for the latter case and should not be used in RSync.

Applied to files:

  • backend/domain_types/src/connector_types.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (3)
backend/domain_types/src/connector_types.rs (2)

65-66: LGTM — ConnectorEnum::Peachpayments registered; snake_case serialization will be "peachpayments".

No issues in this file segment. Please verify repo-wide wiring (mapping, module export, config, tests, NI for unsupported flows).

#!/bin/bash
set -euo pipefail

echo "== convert_connector mapping =="
rg -nP 'fn\s+convert_connector' backend/connector-integration/src/types.rs -C3 || true
rg -n 'Peachpayments' backend/connector-integration/src/types.rs || echo "MISSING: convert_connector mapping to Peachpayments"

echo
echo "== connector module/export =="
fd -t f -I 'peachpayments.rs' backend/connector-integration/src/connectors || echo "MISSING: connectors/peachpayments.rs"
rg -nP 'pub\s+mod\s+peachpayments' backend/connector-integration/src/connectors.rs || echo "MISSING: pub mod peachpayments"
fd -t f -I 'transformers.rs' backend/connector-integration/src/connectors/peachpayments || echo "MISSING: connectors/peachpayments/transformers.rs"

echo
echo "== config entries =="
rg -nC1 'peachpayments' config || echo "MISSING: config peachpayments.* entries"

echo
echo "== proto enum updated =="
rg -n 'PEACHPAYMENTS' backend/grpc-api-types/proto/payment.proto || echo "MISSING: PEACHPAYMENTS in proto"

echo
echo "== unsupported flows explicitly NI (refunds, rsync) =="
rg -nP 'NotImplemented|NotSupported|unimplemented' backend/connector-integration/src/connectors/peachpayments* || echo "MISSING: NI markers for refund/rsync"

echo
echo "== E2E tests =="
fd -t f -I 'peachpayments*_payment_flows_test.rs' backend/grpc-server/tests || echo "MISSING: E2E tests for Peachpayments"

95-96: LGTM — gRPC→domain mapping for Peachpayments added.

This enables inbound gRPC Connector::Peachpayments to be recognized. Ensure proto and any reverse mappings are in sync (covered by the script above).

config/sandbox.toml (1)

45-45: Confirm Peachpayments base_url versioning & trailing-slash semantics

  • Inconsistent across envs: config/sandbox.toml (line 45) and config/development.toml (line 55) use "https://apitest.bankint.ppay.io/v/1"; config/production.toml (line 45) uses "https://api.bankint.peachpayments.com" (no version).
  • Repo search found no Peachpayments connector/impl to verify whether endpoints append a version — risk of double "/v1" or missing version.
  • Public examples use "/v1" (not "/v/1"); confirm which form apitest.bankint.ppay.io expects.

Action: pick one approach and apply consistently across envs — either remove version from configs and have the connector append the canonical "/v1", or normalize all env base_url to include the exact "/v1" (no extra slash) and ensure connector code does not append it.

Comment on lines 161 to 163
Self::deserialize(v.into_deserializer()).unwrap_or_else(|err: serde_json::Error| {
panic!(
"Invalid value found in environment variable {}: {}",
env_key, err
)
panic!("Invalid value found in environment variable {env_key}: {err}")
})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix incorrect error type annotation causing compile error.

Self::deserialize(v.into_deserializer()) uses a serde::de::value::Error (via IntoDeserializer), not serde_json::Error. The explicit annotation mismatches the actual error type. Drop the type to let inference work.

-                Self::deserialize(v.into_deserializer()).unwrap_or_else(|err: serde_json::Error| {
-                    panic!("Invalid value found in environment variable {env_key}: {err}")
-                })
+                Self::deserialize(v.into_deserializer()).unwrap_or_else(|err| {
+                    panic!("Invalid value found in environment variable {env_key}: {err}")
+                })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Self::deserialize(v.into_deserializer()).unwrap_or_else(|err: serde_json::Error| {
panic!(
"Invalid value found in environment variable {}: {}",
env_key, err
)
panic!("Invalid value found in environment variable {env_key}: {err}")
})
Self::deserialize(v.into_deserializer()).unwrap_or_else(|err| {
panic!("Invalid value found in environment variable {env_key}: {err}")
})
🤖 Prompt for AI Agents
In backend/common_utils/src/consts.rs around lines 161 to 163, the closure in
unwrap_or_else currently annotates the error parameter as serde_json::Error
which is incorrect because Self::deserialize(v.into_deserializer()) yields a
serde::de::value::Error via IntoDeserializer; remove the explicit type
annotation from the closure parameter (i.e., use |err| or let inference pick the
type) so the compiler can infer the correct error type and the code compiles.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (6)
backend/grpc-server/tests/peachpayments_payment_flows_test.rs (5)

233-235: Remove arbitrary sleeps; use readiness/polling instead.

Static delays add flakiness and slow CI. Poll for desired status or proceed immediately.

-        // Add delay of 4 seconds
-        tokio::time::sleep(std::time::Duration::from_secs(4)).await;
+        // Consider polling PSync if needed instead of a fixed delay.

287-289: Same: avoid 12s sleep in void test.

Replace with polling or drop if unnecessary.

-        // Add delay of 12 seconds
-        tokio::time::sleep(std::time::Duration::from_secs(12)).await;
+        // Consider polling PSync if needed instead of a fixed delay.

308-311: Make pre-void status check resilient.

Peachpayments may return Pending/AuthenticationPending before Authorize. Restricting to Authorized can flake. Either PSync until Authorized or accept a broader set before proceeding.

-        assert!(
-            auth_response.status == i32::from(PaymentStatus::Authorized),
-            "Payment should be in AUTHORIZED state before voiding"
-        );
+        assert!(
+            [PaymentStatus::Authorized, PaymentStatus::Pending, PaymentStatus::AuthenticationPending]
+                .map(i32::from)
+                .contains(&auth_response.status),
+            "Payment should be in AUTHORIZED/PENDING/AUTHENTICATION_PENDING before voiding"
+        );

31-34: Don’t hardcode merchant id in tests.

Make x-merchant-id configurable via env to match environments.

-const MERCHANT_ID: &str = "merchant_1758520172";
+const MERCHANT_ID: &str = env!("TEST_PEACHPAYMENTS_MERCHANT_ID_HEADER", "merchant_1758520172");

Or read with std::env::var and default if missing.


107-119: Avoid guessing card_network integer.

Using Some(1) is brittle if enum mapping changes. Omit card_network unless required.

-        card_network: Some(1),
+        card_network: None,
backend/connector-integration/src/connectors/peachpayments.rs (1)

381-689: Prune unsupported flow stubs to reduce surface area.

Beyond Refund/RSync, consider removing other empty impls (CreateOrder, SetupMandate, RepeatPayment, Session/AccessToken, Dispute flows) until implemented to avoid accidental routing.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f66a0f6 and d25d72d.

📒 Files selected for processing (2)
  • backend/connector-integration/src/connectors/peachpayments.rs (1 hunks)
  • backend/grpc-server/tests/peachpayments_payment_flows_test.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Create end-to-end tests per connector in backend/grpc-server/tests/<connector>_payment_flows_test.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Create end-to-end tests per connector in backend/grpc-server/tests/<connector>_payment_flows_test.rs

Applied to files:

  • backend/grpc-server/tests/peachpayments_payment_flows_test.rs
  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Write E2E tests covering all supported payment flows, including success and failure paths

Applied to files:

  • backend/grpc-server/tests/peachpayments_payment_flows_test.rs
  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : For every supported flow, use macros::macro_connector_implementation! to wire ConnectorIntegrationV2, specifying defaults, request/response types, headers, URL, and other flow-specific functions

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Put connector-specific request/response structs and TryFrom implementations in backend/connector-integration/src/connectors/<connector>/transformers.rs

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Use macros::create_all_prerequisites! to declare connector struct, supported API flows, optional amount converters, and shared member_functions

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/types.rs : Update convert_connector to map to the new connector

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Define precise request and response structs (and error struct) that match the connector’s API formats

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Create reusable utility functions for request construction (email, address, return URL, connector transaction IDs)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Model connector error variations comprehensively (untagged enums, string errors, empty body cases)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Implement empty marker traits for each supported flow (e.g., PaymentAuthorizeV2, PaymentSyncV2, PaymentCapture)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Persist connector identifiers in response handling (connector_transaction_id, reference_id, mandate_id)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-09-15T06:56:22.535Z
Learnt from: Shubhodip900
PR: juspay/connector-service#172
File: backend/connector-integration/src/connectors/trustpay.rs:747-762
Timestamp: 2025-09-15T06:56:22.535Z
Learning: In Trustpay connector (backend/connector-integration/src/connectors/trustpay.rs), the refund_connector_metadata field has different data formats in different contexts: RSync expects it to be already parsed as JSON Value (accessing directly with .get()), while other refund flows expect it to be a JSON string that needs serde_json::from_str() parsing. The extract_payment_method_from_refund_metadata helper is designed for the latter case and should not be used in RSync.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Provide explicit Not Implemented errors for unsupported payment methods or types when matching over payment_methods/payment_method_types

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-09-15T04:33:18.323Z
Learnt from: Shubhodip900
PR: juspay/connector-service#172
File: backend/grpc-server/tests/trustpay_payment_flows_test.rs:1-4
Timestamp: 2025-09-15T04:33:18.323Z
Learning: In test files for the juspay/connector-service repository, broad Clippy suppressions (#![allow(clippy::expect_used)], #![allow(clippy::unwrap_used)], #![allow(clippy::panic)]) are used as an established coding convention, as confirmed by the maintainer.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Map response_transaction_id and redirect_urls correctly into RouterData fields

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Implement TryFrom<...RouterDataV2...> for connector request types to build outbound payloads

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Avoid hardcoded fallbacks; read values from inputs/resources and return explicit errors when missing

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
🧬 Code graph analysis (2)
backend/grpc-server/tests/peachpayments_payment_flows_test.rs (2)
backend/grpc-server/src/server/health_check.rs (1)
  • check (8-20)
backend/grpc-server/src/server/payments.rs (3)
  • authorize (1117-1233)
  • capture (1704-1709)
  • void (1455-1460)
backend/connector-integration/src/connectors/peachpayments.rs (4)
backend/connector-integration/src/connectors/macros.rs (2)
  • router_data (94-105)
  • request_body (66-75)
backend/domain_types/src/connector_types.rs (3)
  • get_connector_transaction_id (248-257)
  • get_connector_transaction_id (1043-1053)
  • get_connector_transaction_id (1703-1712)
backend/connector-integration/src/connectors/peachpayments/transformers.rs (10)
  • try_from (29-35)
  • try_from (294-381)
  • try_from (400-421)
  • try_from (432-441)
  • try_from (599-656)
  • try_from (675-694)
  • try_from (701-751)
  • try_from (763-815)
  • try_from (827-879)
  • try_from (893-898)
backend/common_utils/src/pii.rs (1)
  • expose (40-42)
🔇 Additional comments (8)
backend/connector-integration/src/connectors/peachpayments.rs (6)

214-248: PSync URL/id extraction looks correct.

Using get_connector_transaction_id with proper error mapping is consistent.

Ensure the Peachpayments API expects GET /transactions/{id} for status. If not, adjust HTTP method/path.


270-283: Capture URL/id extraction OK.

Matches expected /transactions/{id}/confirm and safely extracts id.


335-353: Header construction aligns with BodyKey mapping.

x-api-key, x-tenant-id, and version header are appropriate. Ensure server reads x-key1 and maps to tenant id.

If server expects different header names, adjust try_from in transformers or metadata parsing.


63-70: Remove Refund/RefundSync marker trait impls (not supported).

These advertise refunds as supported contrary to the PR scope.

-impl<T: PaymentMethodDataTypes + Debug + Sync + Send + 'static + Serialize>
-    connector_types::RefundSyncV2 for Peachpayments<T>
-{
-}
-impl<T: PaymentMethodDataTypes + Debug + Sync + Send + 'static + Serialize>
-    connector_types::RefundV2 for Peachpayments<T>
-{
-}

299-315: Fix: use raw connector_transaction_id in Void URL (don’t format enum).

Formatting ResponseId directly yields a debug string, not the raw id.

         fn get_url(
             &self,
             req: &RouterDataV2<Void, PaymentFlowData, PaymentVoidData, PaymentsResponseData>,
         ) -> CustomResult<String, errors::ConnectorError> {
-            let connector_transaction_id = &req.request.connector_transaction_id;
-            Ok(format!(
-                "{}/transactions/{}/reverse",
-                self.connector_base_url_payments(req),
-                connector_transaction_id
-            ))
+            let connector_transaction_id = req
+                .request
+                .connector_transaction_id
+                .get_connector_transaction_id()
+                .change_context(errors::ConnectorError::MissingConnectorTransactionID)?;
+            Ok(format!(
+                "{}/transactions/{}/reverse",
+                self.connector_base_url_payments(req),
+                connector_transaction_id
+            ))
         }

383-406: Remove stubbed ConnectorIntegrationV2 for Refund/RSync.

Empty impls can route unsupported flows and cause runtime confusion.

-impl<
-        T: PaymentMethodDataTypes
-            + std::fmt::Debug
-            + std::marker::Sync
-            + std::marker::Send
-            + 'static
-            + Serialize,
-    > ConnectorIntegrationV2<Refund, RefundFlowData, RefundsData, RefundsResponseData>
-    for Peachpayments<T>
-{
-}
-
-impl<
-        T: PaymentMethodDataTypes
-            + std::fmt::Debug
-            + std::marker::Sync
-            + std::marker::Send
-            + 'static
-            + Serialize,
-    > ConnectorIntegrationV2<RSync, RefundFlowData, RefundSyncData, RefundsResponseData>
-    for Peachpayments<T>
-{
-}
backend/grpc-server/tests/peachpayments_payment_flows_test.rs (2)

181-192: Set minor_amount_to_capture in Peachpayments capture test — verify field exists

Transformer reads minor_amount_to_capture; the test only sets amount_to_capture — add minor_amount_to_capture: TEST_AMOUNT in create_payment_capture_request or confirm PaymentServiceCaptureRequest has no such field.

Location: backend/grpc-server/tests/peachpayments_payment_flows_test.rs — fn create_payment_capture_request


195-207: Incorrect — no change required

FailureReason::from_str maps unknown strings to Timeout (match _ => Ok(Self::Timeout)), and the transformer uses .map(...).transpose()? .unwrap_or(FailureReason::Timeout), so "requested by customer" will not error and effectively behaves like None.

Likely an incorrect or invalid review comment.

Copy link
Collaborator

@Shubhodip900 Shubhodip900 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update the branch. @Anurag-05-prog Please test it via Hyperswitch and attach the curls in description.

// Generate current timestamp for sendDateTime (ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ)
let send_date_time = OffsetDateTime::now_utc()
.format(&time::format_description::well_known::Iso8601::DEFAULT)
.map_err(|_| errors::ConnectorError::RequestEncodingFailed)?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't discard the errors. Use change context

.map_err(|_| errors::ConnectorError::RequestEncodingFailed)?;

Ok(Self {
charge_method: "ecommerce_card_payment_only".to_string(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this is hardcoded. If this is a default value then make it const

) -> Result<Self, Self::Error> {
let send_date_time = OffsetDateTime::now_utc()
.format(&time::format_description::well_known::Iso8601::DEFAULT)
.map_err(|_| errors::ConnectorError::RequestEncodingFailed)?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Change context.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (2)
backend/connector-integration/src/connectors/peachpayments/transformers.rs (2)

51-57: Optional: make charge_method type-safe using the existing PaymentMethod enum.

Avoid free-form strings; serde can serialize snake_case automatically.

Apply this minimal diff (local to this file):

-    pub charge_method: String,
+    pub charge_method: PaymentMethod,
@@
-                Ok(Self {
-                    charge_method: CHARGE_METHOD.to_string(),
+                Ok(Self {
+                    charge_method: PaymentMethod::EcommerceCardPaymentOnly,

And remove the unused CHARGE_METHOD constant if it becomes redundant.


591-670: Add E2E tests for authorize/capture/psync/void flows.

Per our guidelines, add backend/grpc-server/tests/peachpayments_payment_flows_test.rs covering success and failure paths for the implemented flows.

I can scaffold the test module with example cases mirroring the gRPC curl evidence in the PR.

Also applies to: 767-829, 831-893

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 28b31b7f5c4176079777172e8c35cfa0e03311e8 and ff7f039.

📒 Files selected for processing (1)
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Create end-to-end tests per connector in backend/grpc-server/tests/<connector>_payment_flows_test.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Put connector-specific request/response structs and TryFrom implementations in backend/connector-integration/src/connectors/<connector>/transformers.rs

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Define precise request and response structs (and error struct) that match the connector’s API formats

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Model connector error variations comprehensively (untagged enums, string errors, empty body cases)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Create reusable utility functions for request construction (email, address, return URL, connector transaction IDs)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Implement TryFrom<...RouterDataV2...> for connector request types to build outbound payloads

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Implement TryFrom<ResponseRouterData<ConnectorResp, RouterDataV2<...>>> for RouterDataV2 to map connector responses, status, and response data

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Use amount framework types (e.g., MinorUnit) instead of primitive integers for amounts in request/response types

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Persist connector identifiers in response handling (connector_transaction_id, reference_id, mandate_id)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Map response_transaction_id and redirect_urls correctly into RouterData fields

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Avoid hardcoded fallbacks; read values from inputs/resources and return explicit errors when missing

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Use enums for fields with limited value sets instead of generic strings

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Write E2E tests covering all supported payment flows, including success and failure paths

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
🧬 Code graph analysis (1)
backend/connector-integration/src/connectors/peachpayments/transformers.rs (2)
backend/connector-integration/src/utils.rs (1)
  • to_connector_meta_from_secret (63-88)
sdk/python-grpc-client/src/python_grpc_client/generated/payment_pb2.pyi (1)
  • BodyKey (1651-1657)
🔇 Additional comments (2)
backend/connector-integration/src/connectors/peachpayments/transformers.rs (2)

60-61: Fix serde attribute syntax (brackets -> parentheses); current code won’t compile.

Use #[serde(rename_all = "...")] instead of #[serde[rename_all = "..."]] in all the following spots.

Apply this diff:

-#[serde[rename_all = "camelCase"]]
+#[serde(rename_all = "camelCase")]
@@
-#[serde[rename_all = "camelCase"]]
+#[serde(rename_all = "camelCase")]
@@
-#[serde[rename_all = "camelCase"]]
+#[serde(rename_all = "camelCase")]

Also applies to: 503-504, 512-513


559-565: Success detection logic misclassifies outcomes; base it on transaction_result (status), not response_code.

Rely on PeachpaymentsPaymentStatus and pass the ResponseCode only for diagnostics.

Apply this diff:

-fn is_payment_success(value: Option<&String>) -> bool {
-    if let Some(val) = value {
-        val == "00" || val == "08" || val == "X94"
-    } else {
-        false
-    }
-}
+fn is_payment_success(
+    _response_code: Option<&ResponseCode>,
+    status: &PeachpaymentsPaymentStatus,
+) -> bool {
+    match status {
+        PeachpaymentsPaymentStatus::Declined
+        | PeachpaymentsPaymentStatus::Failed
+        | PeachpaymentsPaymentStatus::ThreedsRequired => false,
+        PeachpaymentsPaymentStatus::Voided
+        | PeachpaymentsPaymentStatus::Reversed
+        | PeachpaymentsPaymentStatus::ApprovedConfirmed
+        | PeachpaymentsPaymentStatus::Successful
+        | PeachpaymentsPaymentStatus::Authorized
+        | PeachpaymentsPaymentStatus::Approved
+        | PeachpaymentsPaymentStatus::Pending => true,
+    }
+}

@juspay juspay deleted a comment from coderabbitai bot Sep 24, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
backend/connector-integration/src/connectors/peachpayments/transformers.rs (2)

218-235: Don’t silently coerce unknown failure reasons to Timeout; return an error.

Defaulting unrecognized strings to Timeout hides bad inputs. Make FromStr fail on unknown; keep Timeout only when reason is absent.

 impl FromStr for FailureReason {
     type Err = error_stack::Report<errors::ConnectorError>;

     fn from_str(value: &str) -> Result<Self, Self::Err> {
         match value.to_lowercase().as_str() {
             "unable_to_send" => Ok(Self::UnableToSend),
             "timeout" => Ok(Self::Timeout),
             "security_error" => Ok(Self::SecurityError),
             "issuer_unavailable" => Ok(Self::IssuerUnavailable),
             "too_late_response" => Ok(Self::TooLateResponse),
             "malfunction" => Ok(Self::Malfunction),
             "unable_to_complete" => Ok(Self::UnableToComplete),
             "online_declined" => Ok(Self::OnlineDeclined),
             "suspected_fraud" => Ok(Self::SuspectedFraud),
             "card_declined" => Ok(Self::CardDeclined),
             "partial" => Ok(Self::Partial),
             "offline_declined" => Ok(Self::OfflineDeclined),
             "customer_cancel" => Ok(Self::CustomerCancel),
-            _ => Ok(Self::Timeout),
+            _ => Err(errors::ConnectorError::RequestEncodingFailed.into()),
         }
     }
 }
@@
         Ok(Self {
             payment_method: PaymentMethod::EcommerceCardPaymentOnly,
             send_date_time,
-            failure_reason: item
+            failure_reason: item
                 .router_data
                 .request
                 .cancellation_reason
                 .as_ref()
                 .map(|reason| FailureReason::from_str(reason))
-                .transpose()?
-                .unwrap_or(FailureReason::Timeout),
+                .transpose()?
+                .unwrap_or(FailureReason::Timeout),
         })

Also applies to: 423-431


767-781: Optionally populate network_advice_code from response data.

You can surface ecommerce_card_payment_only_transaction_data.merchant_advice_code into ErrorResponse.network_advice_code for better diagnostics.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff7f039 and e26c603.

📒 Files selected for processing (1)
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Create end-to-end tests per connector in backend/grpc-server/tests/<connector>_payment_flows_test.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Put connector-specific request/response structs and TryFrom implementations in backend/connector-integration/src/connectors/<connector>/transformers.rs

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-09-24T08:45:31.153Z
Learnt from: Anurag-05-prog
PR: juspay/connector-service#188
File: backend/connector-integration/src/connectors/peachpayments.rs:306-315
Timestamp: 2025-09-24T08:45:31.153Z
Learning: In Peachpayments connector (backend/connector-integration/src/connectors/peachpayments.rs), the connector_transaction_id field has different types across flows: PaymentVoidData uses String directly, while PaymentsCaptureData uses ResponseId enum that requires pattern matching or get_connector_transaction_id() method.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Define precise request and response structs (and error struct) that match the connector’s API formats

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Model connector error variations comprehensively (untagged enums, string errors, empty body cases)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Create reusable utility functions for request construction (email, address, return URL, connector transaction IDs)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Implement TryFrom<...RouterDataV2...> for connector request types to build outbound payloads

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Implement TryFrom<ResponseRouterData<ConnectorResp, RouterDataV2<...>>> for RouterDataV2 to map connector responses, status, and response data

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Use amount framework types (e.g., MinorUnit) instead of primitive integers for amounts in request/response types

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Persist connector identifiers in response handling (connector_transaction_id, reference_id, mandate_id)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Map response_transaction_id and redirect_urls correctly into RouterData fields

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Use enums for fields with limited value sets instead of generic strings

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Write E2E tests covering all supported payment flows, including success and failure paths

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-09-24T09:44:04.352Z
Learnt from: Anurag-05-prog
PR: juspay/connector-service#188
File: backend/connector-integration/src/connectors/peachpayments/transformers.rs:275-284
Timestamp: 2025-09-24T09:44:04.352Z
Learning: In the connector service codebase, expiry_year validation is performed at the core layer before reaching connector transformers. If expiry_year length is < 2, a bad request error is thrown at the core layer, ensuring that connector transformer functions like get_card_expiry_year_2_digit() only receive valid input with length >= 2.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-09-15T06:56:22.535Z
Learnt from: Shubhodip900
PR: juspay/connector-service#172
File: backend/connector-integration/src/connectors/trustpay.rs:747-762
Timestamp: 2025-09-15T06:56:22.535Z
Learning: In Trustpay connector (backend/connector-integration/src/connectors/trustpay.rs), the refund_connector_metadata field has different data formats in different contexts: RSync expects it to be already parsed as JSON Value (accessing directly with .get()), while other refund flows expect it to be a JSON string that needs serde_json::from_str() parsing. The extract_payment_method_from_refund_metadata helper is designed for the latter case and should not be used in RSync.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Avoid hardcoded fallbacks; read values from inputs/resources and return explicit errors when missing

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Create end-to-end tests per connector in backend/grpc-server/tests/<connector>_payment_flows_test.rs

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Implement status mapping per HS standards; default status should be pending

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Implement empty marker traits for each supported flow (e.g., PaymentAuthorizeV2, PaymentSyncV2, PaymentCapture)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
🧬 Code graph analysis (1)
backend/connector-integration/src/connectors/peachpayments/transformers.rs (2)
backend/connector-integration/src/connectors/macros.rs (1)
  • router_data (94-105)
backend/connector-integration/src/utils.rs (1)
  • to_connector_meta_from_secret (63-88)
🔇 Additional comments (3)
backend/connector-integration/src/connectors/peachpayments/transformers.rs (3)

375-378: Confirm required timestamp format for send_date_time.

Iso8601::DEFAULT may include fractional seconds; docs/example show “YYYY-MM-DDTHH:MM:SSZ”. If seconds-only are required, switch to an explicit format.

- let send_date_time = OffsetDateTime::now_utc()
-     .format(&time::format_description::well_known::Iso8601::DEFAULT)
+ let fmt = time::format_description::parse("[year]-[month]-[day]T[hour]:[minute]:[second]Z")
+     .map_err(|_| errors::ConnectorError::RequestEncodingFailed)?
+ let send_date_time = OffsetDateTime::now_utc()
+     .format(&fmt)

274-282: Good defensive check on 2‑digit expiry extraction.

Prevents underflow; aligns with earlier guidance about core-layer validation.


58-60: Fix serde attribute syntax (still using brackets) — code won’t compile.

Replace #[serde[rename_all = "..."]] with #[serde(rename_all = "...")] in these places.

-#[derive(Debug, Clone, Serialize, PartialEq)]
-#[serde[rename_all = "camelCase"]]
+#[derive(Debug, Clone, Serialize, PartialEq)]
+#[serde(rename_all = "camelCase")]
 pub struct EcommerceCardPaymentOnlyTransactionData<
@@
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-#[serde[rename_all = "camelCase"]]
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "camelCase")]
 pub struct PeachpaymentsConfirmResponse {
@@
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-#[serde[rename_all = "camelCase"]]
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "camelCase")]
 #[serde(untagged)]
 pub enum ResponseCode {

Also applies to: 499-502, 509-511

Comment on lines +74 to +98
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct MerchantInformation {
pub client_merchant_reference_id: Secret<String>,
pub name: Secret<String>,
pub mcc: Secret<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub phone: Option<Secret<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<pii::Email>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mobile: Option<Secret<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub address: Option<Secret<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub city: Option<Secret<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub postal_code: Option<Secret<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub region_code: Option<Secret<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub merchant_type: Option<MerchantType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub website_url: Option<url::Url>,
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 Analysis chain

Ensure url::Url has serde feature enabled in Cargo.

This struct is serialized; url requires the “serde” feature. Please verify dependency flags.


🏁 Script executed:

#!/bin/bash
# Check url crate usage and features across workspace
rg -n --glob 'Cargo.toml' '^\s*url\s*=\s*'
rg -n --glob 'Cargo.toml' -C2 '^\s*url\s*=\s*\{.*\}'
rg -n --glob 'Cargo.toml' -C2 '^\s*url\s*=\s*".*"$'

Length of output: 1851


Enable serde feature for url in connector-integration Cargo.toml

backend/connector-integration/Cargo.toml currently has url = "2.5.0" (line 22) but MerchantInformation serializes url::Url — change to url = { version = "2.5.0", features = ["serde"] } or otherwise ensure the workspace resolution enables serde for url (domain_types already enables it for v2.5.4, but don’t rely on transitive propagation).

Location: backend/connector-integration/Cargo.toml:22

🤖 Prompt for AI Agents
backend/connector-integration/Cargo.toml around line 22: the crate currently
lists url = "2.5.0" but the code serializes url::Url in MerchantInformation, so
enable the serde feature on url by changing the dependency to include features
(e.g. url = { version = "2.5.0", features = ["serde"] }) or otherwise ensure the
workspace dependency resolution explicitly enables serde for url; after editing,
run cargo update / cargo check to verify builds.

Comment on lines +492 to +497
pub struct PeachpaymentsPaymentsResponse {
pub transaction_id: String,
pub response_code: Option<ResponseCode>,
pub transaction_result: PeachpaymentsPaymentStatus,
pub ecommerce_card_payment_only_transaction_data: Option<EcommerceCardPaymentOnlyResponseData>,
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Model and persist responseRefId (present in real responses).

Testing artifacts show responseRefId; currently we don’t capture it and reuse transaction_id instead. Add the field and map it to connector_response_reference_id, falling back to transaction_id if missing.

 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 pub struct PeachpaymentsPaymentsResponse {
     pub transaction_id: String,
     pub response_code: Option<ResponseCode>,
     pub transaction_result: PeachpaymentsPaymentStatus,
     pub ecommerce_card_payment_only_transaction_data: Option<EcommerceCardPaymentOnlyResponseData>,
+    pub response_ref_id: Option<String>,
 }
@@
-#[serde[rename_all = "camelCase"]]
+#[serde(rename_all = "camelCase")]
 pub struct PeachpaymentsConfirmResponse {
     pub transaction_id: String,
     pub response_code: Option<ResponseCode>,
     pub transaction_result: PeachpaymentsPaymentStatus,
     pub authorization_code: Option<String>,
+    pub response_ref_id: Option<String>,
 }
@@
-                connector_response_reference_id: Some(item.response.transaction_id),
+                connector_response_reference_id: item
+                    .response
+                    .response_ref_id
+                    .clone()
+                    .or(Some(item.response.transaction_id.clone())),
@@
-                connector_response_reference_id: Some(item.response.transaction_id),
+                connector_response_reference_id: item
+                    .response
+                    .response_ref_id
+                    .clone()
+                    .or(Some(item.response.transaction_id.clone())),
@@
-                connector_response_reference_id: Some(item.response.transaction_id),
+                connector_response_reference_id: item
+                    .response
+                    .response_ref_id
+                    .clone()
+                    .or(Some(item.response.transaction_id.clone())),
@@
-                connector_response_reference_id: Some(item.response.transaction_id),
+                connector_response_reference_id: item
+                    .response
+                    .response_ref_id
+                    .clone()
+                    .or(Some(item.response.transaction_id.clone())),

Also applies to: 503-507, 641-644, 732-734, 791-794, 851-854

Shubhodip900
Shubhodip900 previously approved these changes Sep 26, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (5)
backend/connector-integration/src/connectors/peachpayments.rs (3)

289-299: Unify capture URL id extraction with get_connector_transaction_id().

Use the helper for consistency and better error context; mirrors PSync.

Apply this diff:

-            let connector_transaction_id = match &req.request.connector_transaction_id {
-                ResponseId::ConnectorTransactionId(id) => id,
-                _ => return Err(errors::ConnectorError::MissingConnectorTransactionID.into())
-            };
+            let connector_transaction_id = req
+                .request
+                .connector_transaction_id
+                .get_connector_transaction_id()
+                .change_context(errors::ConnectorError::MissingConnectorTransactionID)?;
             Ok(format!(
                 "{}/transactions/{}/confirm",
                 self.connector_base_url_payments(req),
                 connector_transaction_id
             ))

Based on learnings


361-368: Avoid magic string for x-exi-auth-ver.

Promote "v1" to a const for clarity and reuse.

Apply this diff:

 pub(crate) mod headers {
     pub(crate) const CONTENT_TYPE: &str = "Content-Type";
+    pub(crate) const EXI_AUTH_VERSION: &str = "v1";
 }
@@
-            ("x-exi-auth-ver".to_string(), "v1".to_string().into_masked()),
+            ("x-exi-auth-ver".to_string(), headers::EXI_AUTH_VERSION.to_string().into_masked()),

595-613: Also drop SourceVerification impls for Refund/RSync.

These imply support; remove until flows are implemented.

Apply this diff:

-impl<T: PaymentMethodDataTypes + Debug + Sync + Send + 'static + Serialize>
-    interfaces::verification::SourceVerification<
-        Refund,
-        RefundFlowData,
-        RefundsData,
-        RefundsResponseData,
-    > for Peachpayments<T>
-{
-}
-
-impl<T: PaymentMethodDataTypes + Debug + Sync + Send + 'static + Serialize>
-    interfaces::verification::SourceVerification<
-        RSync,
-        RefundFlowData,
-        RefundSyncData,
-        RefundsResponseData,
-    > for Peachpayments<T>
-{
-}
backend/connector-integration/src/connectors/peachpayments/transformers.rs (2)

492-507: Capture responseRefId from Peach responses.

Artifacts show responseRefId; persist it to connector_response_reference_id (fallback to transaction_id).

Apply this diff:

 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 pub struct PeachpaymentsPaymentsResponse {
     pub transaction_id: String,
     pub response_code: Option<ResponseCode>,
     pub transaction_result: PeachpaymentsPaymentStatus,
     pub ecommerce_card_payment_only_transaction_data: Option<EcommerceCardPaymentOnlyResponseData>,
+    #[serde(rename = "responseRefId")]
+    pub response_ref_id: Option<String>,
 }
@@
 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 pub struct PeachpaymentsConfirmResponse {
     pub transaction_id: String,
     pub response_code: Option<ResponseCode>,
     pub transaction_result: PeachpaymentsPaymentStatus,
     pub authorization_code: Option<String>,
+    #[serde(rename = "responseRefId")]
+    pub response_ref_id: Option<String>,
 }
@@
-                connector_response_reference_id: Some(item.response.transaction_id),
+                connector_response_reference_id: item
+                    .response
+                    .response_ref_id
+                    .clone()
+                    .or(Some(item.response.transaction_id.clone())),
@@
-                connector_response_reference_id: Some(item.response.transaction_id),
+                connector_response_reference_id: item
+                    .response
+                    .response_ref_id
+                    .clone()
+                    .or(Some(item.response.transaction_id.clone())),
@@
-                connector_response_reference_id: Some(item.response.transaction_id),
+                connector_response_reference_id: item
+                    .response
+                    .response_ref_id
+                    .clone()
+                    .or(Some(item.response.transaction_id.clone())),
@@
-                connector_response_reference_id: Some(item.response.transaction_id),
+                connector_response_reference_id: item
+                    .response
+                    .response_ref_id
+                    .clone()
+                    .or(Some(item.response.transaction_id.clone())),

Also applies to: 613-645, 719-734, 783-794, 843-854


215-236: Consider failing on unknown failure_reason instead of defaulting to Timeout.

Defaulting may mask bad inputs; returning an error or logging would be safer.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1a21e57 and 5d6ab24.

📒 Files selected for processing (10)
  • backend/connector-integration/src/connectors.rs (1 hunks)
  • backend/connector-integration/src/connectors/peachpayments.rs (1 hunks)
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs (1 hunks)
  • backend/connector-integration/src/types.rs (2 hunks)
  • backend/domain_types/src/connector_types.rs (2 hunks)
  • backend/domain_types/src/types.rs (1 hunks)
  • backend/grpc-api-types/proto/payment.proto (1 hunks)
  • config/development.toml (1 hunks)
  • config/production.toml (1 hunks)
  • config/sandbox.toml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • backend/connector-integration/src/types.rs
  • config/sandbox.toml
  • backend/grpc-api-types/proto/payment.proto
  • backend/domain_types/src/connector_types.rs
  • backend/domain_types/src/types.rs
  • config/production.toml
  • backend/connector-integration/src/connectors.rs
🧰 Additional context used
🧠 Learnings (27)
📓 Common learnings
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Create end-to-end tests per connector in backend/grpc-server/tests/<connector>_payment_flows_test.rs
Learnt from: Anurag-05-prog
PR: juspay/connector-service#188
File: backend/connector-integration/src/connectors/peachpayments.rs:306-315
Timestamp: 2025-09-24T08:45:31.195Z
Learning: In Peachpayments connector (backend/connector-integration/src/connectors/peachpayments.rs), the connector_transaction_id field has different types across flows: PaymentVoidData uses String directly, while PaymentsCaptureData uses ResponseId enum that requires pattern matching or get_connector_transaction_id() method.
Learnt from: Anurag-05-prog
PR: juspay/connector-service#188
File: backend/connector-integration/src/connectors/peachpayments/transformers.rs:50-56
Timestamp: 2025-09-24T10:18:33.115Z
Learning: In Peach Payments connector API (backend/connector-integration/src/connectors/peachpayments/transformers.rs), the authorize request struct uses the field "charge_method" as expected by the Peach Payments API, not "paymentType" or other variations.
📚 Learning: 2025-09-24T08:45:31.195Z
Learnt from: Anurag-05-prog
PR: juspay/connector-service#188
File: backend/connector-integration/src/connectors/peachpayments.rs:306-315
Timestamp: 2025-09-24T08:45:31.195Z
Learning: In Peachpayments connector (backend/connector-integration/src/connectors/peachpayments.rs), the connector_transaction_id field has different types across flows: PaymentVoidData uses String directly, while PaymentsCaptureData uses ResponseId enum that requires pattern matching or get_connector_transaction_id() method.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : For every supported flow, use macros::macro_connector_implementation! to wire ConnectorIntegrationV2, specifying defaults, request/response types, headers, URL, and other flow-specific functions

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-09-24T10:18:33.115Z
Learnt from: Anurag-05-prog
PR: juspay/connector-service#188
File: backend/connector-integration/src/connectors/peachpayments/transformers.rs:50-56
Timestamp: 2025-09-24T10:18:33.115Z
Learning: In Peach Payments connector API (backend/connector-integration/src/connectors/peachpayments/transformers.rs), the authorize request struct uses the field "charge_method" as expected by the Peach Payments API, not "paymentType" or other variations.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Create end-to-end tests per connector in backend/grpc-server/tests/<connector>_payment_flows_test.rs

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Use macros::create_all_prerequisites! to declare connector struct, supported API flows, optional amount converters, and shared member_functions

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Put connector-specific request/response structs and TryFrom implementations in backend/connector-integration/src/connectors/<connector>/transformers.rs

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/types.rs : Update convert_connector to map to the new connector

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-09-15T06:56:22.535Z
Learnt from: Shubhodip900
PR: juspay/connector-service#172
File: backend/connector-integration/src/connectors/trustpay.rs:747-762
Timestamp: 2025-09-15T06:56:22.535Z
Learning: In Trustpay connector (backend/connector-integration/src/connectors/trustpay.rs), the refund_connector_metadata field has different data formats in different contexts: RSync expects it to be already parsed as JSON Value (accessing directly with .get()), while other refund flows expect it to be a JSON string that needs serde_json::from_str() parsing. The extract_payment_method_from_refund_metadata helper is designed for the latter case and should not be used in RSync.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Implement empty marker traits for each supported flow (e.g., PaymentAuthorizeV2, PaymentSyncV2, PaymentCapture)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Provide explicit Not Implemented errors for unsupported payment methods or types when matching over payment_methods/payment_method_types

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-09-15T04:33:18.323Z
Learnt from: Shubhodip900
PR: juspay/connector-service#172
File: backend/grpc-server/tests/trustpay_payment_flows_test.rs:1-4
Timestamp: 2025-09-15T04:33:18.323Z
Learning: In test files for the juspay/connector-service repository, broad Clippy suppressions (#![allow(clippy::expect_used)], #![allow(clippy::unwrap_used)], #![allow(clippy::panic)]) are used as an established coding convention, as confirmed by the maintainer.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Create reusable utility functions for request construction (email, address, return URL, connector transaction IDs)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Map response_transaction_id and redirect_urls correctly into RouterData fields

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Persist connector identifiers in response handling (connector_transaction_id, reference_id, mandate_id)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Define precise request and response structs (and error struct) that match the connector’s API formats

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Model connector error variations comprehensively (untagged enums, string errors, empty body cases)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Implement TryFrom<...RouterDataV2...> for connector request types to build outbound payloads

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Avoid hardcoded fallbacks; read values from inputs/resources and return explicit errors when missing

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-09-26T08:08:52.592Z
Learnt from: Shubhodip900
PR: juspay/connector-service#193
File: backend/connector-integration/src/connectors/rapyd/transformers.rs:505-524
Timestamp: 2025-09-26T08:08:52.592Z
Learning: In Rapyd connector (backend/connector-integration/src/connectors/rapyd/transformers.rs), the next_action field in ResponseData struct is required (not Optional) as per Rapyd API documentation. This field always appears in payment responses with values like "3d_verification", "pending_capture", "pending_confirmation", or "not_applicable", consistent with hyperswitch connector patterns.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Write E2E tests covering all supported payment flows, including success and failure paths

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Implement TryFrom<ResponseRouterData<ConnectorResp, RouterDataV2<...>>> for RouterDataV2 to map connector responses, status, and response data

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Use amount framework types (e.g., MinorUnit) instead of primitive integers for amounts in request/response types

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Use enums for fields with limited value sets instead of generic strings

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Use proper option chaining and error propagation instead of random default values

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-09-24T09:44:04.430Z
Learnt from: Anurag-05-prog
PR: juspay/connector-service#188
File: backend/connector-integration/src/connectors/peachpayments/transformers.rs:275-284
Timestamp: 2025-09-24T09:44:04.430Z
Learning: In the connector service codebase, expiry_year validation is performed at the core layer before reaching connector transformers. If expiry_year length is < 2, a bad request error is thrown at the core layer, ensuring that connector transformer functions like get_card_expiry_year_2_digit() only receive valid input with length >= 2.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Implement status mapping per HS standards; default status should be pending

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments/transformers.rs
🧬 Code graph analysis (2)
backend/connector-integration/src/connectors/peachpayments.rs (3)
backend/connector-integration/src/connectors/macros.rs (2)
  • router_data (94-105)
  • request_body (66-75)
backend/domain_types/src/connector_types.rs (3)
  • get_connector_transaction_id (253-262)
  • get_connector_transaction_id (1074-1084)
  • get_connector_transaction_id (1824-1833)
backend/connector-integration/src/connectors/peachpayments/transformers.rs (10)
  • try_from (30-36)
  • try_from (305-392)
  • try_from (411-432)
  • try_from (443-452)
  • try_from (602-655)
  • try_from (674-693)
  • try_from (700-745)
  • try_from (757-805)
  • try_from (817-865)
  • try_from (879-884)
backend/connector-integration/src/connectors/peachpayments/transformers.rs (3)
backend/connector-integration/src/connectors/macros.rs (1)
  • router_data (94-105)
backend/connector-integration/src/utils.rs (1)
  • to_connector_meta_from_secret (63-88)
sdk/python-grpc-client/src/python_grpc_client/generated/payment_pb2.pyi (1)
  • BodyKey (1651-1657)
🔇 Additional comments (6)
config/development.toml (1)

57-57: LGTM: Added PeachPayments base_url.

Key name matches code expectations (connectors.peachpayments.base_url). The trailing path composes correctly with "/transactions".

backend/connector-integration/src/connectors/peachpayments/transformers.rs (3)

274-282: Expiry year guard looks good.

Underflow risk handled; safe 2‑digit extraction.


320-338: Good: metadata parsing with context.

Uses to_connector_meta_from_secret and change_context for InvalidConnectorConfig.


97-98: Enable serde feature on url crate in connector-integration
In backend/connector-integration/Cargo.toml, change

url = "2.5.0"

to

url = { version = "2.5.0", features = ["serde"] }

so that url::Url can derive Serialize/Deserialize for website_url.

backend/connector-integration/src/connectors/peachpayments.rs (2)

65-71: Don’t advertise Refund/RSync support (marker traits).

PR explicitly says refunds/rsync are not implemented. These impls suggest support.

Apply this diff to remove:

-impl<T: PaymentMethodDataTypes + Debug + Sync + Send + 'static + Serialize>
-    connector_types::RefundSyncV2 for Peachpayments<T>
-{
-}
-impl<T: PaymentMethodDataTypes + Debug + Sync + Send + 'static + Serialize>
-    connector_types::RefundV2 for Peachpayments<T>
-{
-}

399-421: Remove stub ConnectorIntegrationV2 for Refund and RSync.

Empty impls can cause routing to unsupported flows.

Apply this diff:

-impl<
-        T: PaymentMethodDataTypes
-            + std::fmt::Debug
-            + std::marker::Sync
-            + std::marker::Send
-            + 'static
-            + Serialize,
-    > ConnectorIntegrationV2<Refund, RefundFlowData, RefundsData, RefundsResponseData>
-    for Peachpayments<T>
-{
-}
-
-impl<
-        T: PaymentMethodDataTypes
-            + std::fmt::Debug
-            + std::marker::Sync
-            + std::marker::Send
-            + 'static
-            + Serialize,
-    > ConnectorIntegrationV2<RSync, RefundFlowData, RefundSyncData, RefundsResponseData>
-    for Peachpayments<T>
-{
-}

Shubhodip900
Shubhodip900 previously approved these changes Sep 26, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
backend/connector-integration/src/connectors/peachpayments.rs (1)

400-422: Duplicate: Empty Refund/RSync integration impls were previously flagged.

These empty ConnectorIntegrationV2 implementations for Refund and RSync were flagged in a previous review as potentially confusing since the PR states these flows are not implemented. The previous review suggested removing them to avoid runtime "supported but unimplemented" confusion.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4a45f7d and 6f24ebd.

📒 Files selected for processing (1)
  • backend/connector-integration/src/connectors/peachpayments.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Create end-to-end tests per connector in backend/grpc-server/tests/<connector>_payment_flows_test.rs
📚 Learning: 2025-09-24T08:45:31.195Z
Learnt from: Anurag-05-prog
PR: juspay/connector-service#188
File: backend/connector-integration/src/connectors/peachpayments.rs:306-315
Timestamp: 2025-09-24T08:45:31.195Z
Learning: In Peachpayments connector (backend/connector-integration/src/connectors/peachpayments.rs), the connector_transaction_id field has different types across flows: PaymentVoidData uses String directly, while PaymentsCaptureData uses ResponseId enum that requires pattern matching or get_connector_transaction_id() method.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : For every supported flow, use macros::macro_connector_implementation! to wire ConnectorIntegrationV2, specifying defaults, request/response types, headers, URL, and other flow-specific functions

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-09-15T06:56:22.535Z
Learnt from: Shubhodip900
PR: juspay/connector-service#172
File: backend/connector-integration/src/connectors/trustpay.rs:747-762
Timestamp: 2025-09-15T06:56:22.535Z
Learning: In Trustpay connector (backend/connector-integration/src/connectors/trustpay.rs), the refund_connector_metadata field has different data formats in different contexts: RSync expects it to be already parsed as JSON Value (accessing directly with .get()), while other refund flows expect it to be a JSON string that needs serde_json::from_str() parsing. The extract_payment_method_from_refund_metadata helper is designed for the latter case and should not be used in RSync.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Implement empty marker traits for each supported flow (e.g., PaymentAuthorizeV2, PaymentSyncV2, PaymentCapture)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Provide explicit Not Implemented errors for unsupported payment methods or types when matching over payment_methods/payment_method_types

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Create reusable utility functions for request construction (email, address, return URL, connector transaction IDs)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Map response_transaction_id and redirect_urls correctly into RouterData fields

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Persist connector identifiers in response handling (connector_transaction_id, reference_id, mandate_id)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-09-24T10:18:33.115Z
Learnt from: Anurag-05-prog
PR: juspay/connector-service#188
File: backend/connector-integration/src/connectors/peachpayments/transformers.rs:50-56
Timestamp: 2025-09-24T10:18:33.115Z
Learning: In Peach Payments connector API (backend/connector-integration/src/connectors/peachpayments/transformers.rs), the authorize request struct uses the field "charge_method" as expected by the Peach Payments API, not "paymentType" or other variations.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
🧬 Code graph analysis (1)
backend/connector-integration/src/connectors/peachpayments.rs (4)
backend/connector-integration/src/connectors/macros.rs (2)
  • router_data (94-105)
  • request_body (66-75)
backend/domain_types/src/connector_types.rs (3)
  • get_connector_transaction_id (257-266)
  • get_connector_transaction_id (1078-1088)
  • get_connector_transaction_id (1828-1837)
backend/common_utils/src/request.rs (2)
  • headers (164-167)
  • header (159-162)
backend/connector-integration/src/connectors/peachpayments/transformers.rs (10)
  • try_from (30-36)
  • try_from (305-392)
  • try_from (411-432)
  • try_from (443-452)
  • try_from (602-655)
  • try_from (674-693)
  • try_from (700-745)
  • try_from (757-805)
  • try_from (817-865)
  • try_from (879-884)
🪛 GitHub Actions: CI
backend/connector-integration/src/connectors/peachpayments.rs

[error] 18-18: unused import: ResponseId. Clippy error: to override -D warnings add #[allow(unused_imports)]

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (2)
backend/connector-integration/src/connectors/peachpayments.rs (2)

322-332: LGTM: Void URL construction is correct.

The direct use of connector_transaction_id as a String is correct for the Void flow, as confirmed in previous review discussions.

Based on learnings.


336-396: LGTM: ConnectorCommon implementation follows standard patterns.

The implementation correctly:

  • Identifies the connector
  • Uses minor currency units (cents) as documented
  • Builds appropriate auth headers (x-api-key, x-tenant-id, x-exi-auth-ver)
  • Handles error responses

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
backend/connector-integration/src/connectors/peachpayments.rs (3)

5-20: Remove unused import: ResponseId.

This import is unused in this file and causes a pipeline error. ResponseId is only used in transformers.rs.

Apply this diff:

         PaymentsPostAuthenticateData, PaymentsPreAuthenticateData, PaymentsResponseData,
-        PaymentsSyncData, RefundFlowData, RefundSyncData, RefundsData, RefundsResponseData,
-        RepeatPaymentData, ResponseId, SessionTokenRequestData, SessionTokenResponseData,
+        PaymentsSyncData, RefundFlowData, RefundSyncData, RefundsData, RefundsResponseData,
+        RepeatPaymentData, SessionTokenRequestData, SessionTokenResponseData,
         SetupMandateRequestData, SubmitEvidenceData,

64-71: Remove marker traits for unsupported Refund/RSync flows.

The PR states that refunds and RSync are not implemented. These marker trait implementations advertise support but have no actual implementation, which could cause routing confusion.

Apply this diff:

-impl<T: PaymentMethodDataTypes + Debug + Sync + Send + 'static + Serialize>
-    connector_types::RefundSyncV2 for Peachpayments<T>
-{
-}
-impl<T: PaymentMethodDataTypes + Debug + Sync + Send + 'static + Serialize>
-    connector_types::RefundV2 for Peachpayments<T>
-{
-}
 impl<T: PaymentMethodDataTypes + Debug + Sync + Send + 'static + Serialize>
     connector_types::PaymentCapture for Peachpayments<T>
 {

400-422: Remove stub implementations for Refund and RSync flows.

These empty ConnectorIntegrationV2 implementations advertise support for Refund and RSync but have no actual functionality. This can cause runtime "supported but unimplemented" errors when these flows are attempted.

Apply this diff:

-// Stub implementations for unsupported flows
-
-impl<
-        T: PaymentMethodDataTypes
-            + std::fmt::Debug
-            + std::marker::Sync
-            + std::marker::Send
-            + 'static
-            + Serialize,
-    > ConnectorIntegrationV2<Refund, RefundFlowData, RefundsData, RefundsResponseData>
-    for Peachpayments<T>
-{
-}
-
-impl<
-        T: PaymentMethodDataTypes
-            + std::fmt::Debug
-            + std::marker::Sync
-            + std::marker::Send
-            + 'static
-            + Serialize,
-    > ConnectorIntegrationV2<RSync, RefundFlowData, RefundSyncData, RefundsResponseData>
-    for Peachpayments<T>
-{
-}
-
 impl<
         T: PaymentMethodDataTypes
             + std::fmt::Debug
🧹 Nitpick comments (1)
backend/connector-integration/src/connectors/peachpayments.rs (1)

424-736: Consider removing other stub implementations for consistency.

While the Refund/RSync stubs are the most problematic, this file also contains empty ConnectorIntegrationV2 implementations for other unsupported flows (CreateOrder, SubmitEvidence, DefendDispute, Accept, SetupMandate, RepeatPayment, CreateSessionToken, CreateAccessToken, PaymentMethodToken, PreAuthenticate, Authenticate, PostAuthenticate).

For consistency and to avoid runtime confusion, consider either:

  1. Removing all empty stub implementations (preferred), or
  2. Adding TODO comments clearly documenting these as placeholders for future implementation

The SourceVerification trait implementations (lines 556-766) are acceptable as they're marker traits.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6f24ebd and 448e2a8.

📒 Files selected for processing (1)
  • backend/connector-integration/src/connectors/peachpayments.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Create end-to-end tests per connector in backend/grpc-server/tests/<connector>_payment_flows_test.rs
📚 Learning: 2025-09-24T08:45:31.195Z
Learnt from: Anurag-05-prog
PR: juspay/connector-service#188
File: backend/connector-integration/src/connectors/peachpayments.rs:306-315
Timestamp: 2025-09-24T08:45:31.195Z
Learning: In Peachpayments connector (backend/connector-integration/src/connectors/peachpayments.rs), the connector_transaction_id field has different types across flows: PaymentVoidData uses String directly, while PaymentsCaptureData uses ResponseId enum that requires pattern matching or get_connector_transaction_id() method.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-09-24T10:18:33.115Z
Learnt from: Anurag-05-prog
PR: juspay/connector-service#188
File: backend/connector-integration/src/connectors/peachpayments/transformers.rs:50-56
Timestamp: 2025-09-24T10:18:33.115Z
Learning: In Peach Payments connector API (backend/connector-integration/src/connectors/peachpayments/transformers.rs), the authorize request struct uses the field "charge_method" as expected by the Peach Payments API, not "paymentType" or other variations.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-09-15T06:56:22.535Z
Learnt from: Shubhodip900
PR: juspay/connector-service#172
File: backend/connector-integration/src/connectors/trustpay.rs:747-762
Timestamp: 2025-09-15T06:56:22.535Z
Learning: In Trustpay connector (backend/connector-integration/src/connectors/trustpay.rs), the refund_connector_metadata field has different data formats in different contexts: RSync expects it to be already parsed as JSON Value (accessing directly with .get()), while other refund flows expect it to be a JSON string that needs serde_json::from_str() parsing. The extract_payment_method_from_refund_metadata helper is designed for the latter case and should not be used in RSync.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Implement empty marker traits for each supported flow (e.g., PaymentAuthorizeV2, PaymentSyncV2, PaymentCapture)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Provide explicit Not Implemented errors for unsupported payment methods or types when matching over payment_methods/payment_method_types

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Create reusable utility functions for request construction (email, address, return URL, connector transaction IDs)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Map response_transaction_id and redirect_urls correctly into RouterData fields

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Persist connector identifiers in response handling (connector_transaction_id, reference_id, mandate_id)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : For every supported flow, use macros::macro_connector_implementation! to wire ConnectorIntegrationV2, specifying defaults, request/response types, headers, URL, and other flow-specific functions

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
🧬 Code graph analysis (1)
backend/connector-integration/src/connectors/peachpayments.rs (4)
backend/connector-integration/src/connectors/macros.rs (2)
  • router_data (94-105)
  • request_body (66-75)
backend/domain_types/src/connector_types.rs (3)
  • get_connector_transaction_id (257-266)
  • get_connector_transaction_id (1078-1088)
  • get_connector_transaction_id (1828-1837)
backend/connector-integration/src/connectors/peachpayments/transformers.rs (10)
  • try_from (30-36)
  • try_from (305-392)
  • try_from (411-432)
  • try_from (443-452)
  • try_from (602-655)
  • try_from (674-693)
  • try_from (700-745)
  • try_from (757-805)
  • try_from (817-865)
  • try_from (879-884)
backend/common_utils/src/pii.rs (1)
  • expose (40-42)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (5)
backend/connector-integration/src/connectors/peachpayments.rs (5)

136-200: LGTM with minor note.

The headers module and macro prerequisites are correctly structured for the four supported flows (Authorize, PSync, Capture, Void). The connector_base_url_refunds helper is defined but unused since refunds are not implemented—this can be kept for future implementation.


202-228: LGTM!

The Authorize flow implementation correctly uses the macro pattern with proper request/response types, HTTP method, and URL construction.


230-264: LGTM!

The PSync flow implementation correctly extracts the connector transaction ID from the ResponseId enum and handles the error case appropriately.


266-334: LGTM!

Both Capture and Void flow implementations are correct. The Capture flow properly extracts the transaction ID from ResponseId enum, while the Void flow correctly uses the String directly since PaymentVoidData.connector_transaction_id is a String type (not ResponseId).


336-396: LGTM!

The ConnectorCommon implementation is complete and correct. Currency unit is properly set to Minor (cents), authentication headers are correctly constructed with the three required headers, and error response handling is appropriate.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
backend/connector-integration/src/connectors/peachpayments.rs (2)

66-73: Critical: Remove marker traits for unsupported Refund flows.

These trait implementations advertise that Refund and RefundSync are supported, but the PR description explicitly states refunds are not implemented. This was previously flagged and marked as addressed, but the traits are still present in the current code.

Remove these marker trait implementations to prevent the connector from being routed to unsupported flows:

-impl<T: PaymentMethodDataTypes + Debug + Sync + Send + 'static + Serialize>
-    connector_types::RefundSyncV2 for Peachpayments<T>
-{
-}
-impl<T: PaymentMethodDataTypes + Debug + Sync + Send + 'static + Serialize>
-    connector_types::RefundV2 for Peachpayments<T>
-{
-}

412-434: Critical: Remove empty Refund/RSync integration stubs.

These empty ConnectorIntegrationV2 implementations, combined with the marker traits at lines 66-73, falsely advertise that Refund and RSync are supported. This can cause runtime failures when these flows are attempted.

Remove both the marker traits (lines 66-73) and these empty integration implementations:

-impl<
-        T: PaymentMethodDataTypes
-            + std::fmt::Debug
-            + std::marker::Sync
-            + std::marker::Send
-            + 'static
-            + Serialize,
-    > ConnectorIntegrationV2<Refund, RefundFlowData, RefundsData, RefundsResponseData>
-    for Peachpayments<T>
-{
-}
-
-impl<
-        T: PaymentMethodDataTypes
-            + std::fmt::Debug
-            + std::marker::Sync
-            + std::marker::Send
-            + 'static
-            + Serialize,
-    > ConnectorIntegrationV2<RSync, RefundFlowData, RefundSyncData, RefundsResponseData>
-    for Peachpayments<T>
-{
-}
🧹 Nitpick comments (1)
backend/connector-integration/src/connectors/peachpayments.rs (1)

436-758: Consider removing all empty integration stubs for consistency.

Similar to the Refund/RSync stubs, this file contains empty ConnectorIntegrationV2 implementations for many other flows (CreateOrder, SubmitEvidence, DefendDispute, Accept, SetupMandate, RepeatPayment, CreateSessionToken, PreAuthenticate, Authenticate, PostAuthenticate, CreateConnectorCustomer, CreateAccessToken, PaymentMethodToken).

These empty implementations combined with their corresponding marker traits (lines 78-146) can cause the same "supported but unimplemented" confusion as the Refund flows.

For consistency and to prevent routing issues, consider removing both:

  1. The marker trait implementations (lines 78-146) for truly unsupported flows
  2. The empty ConnectorIntegrationV2 implementations (lines 436-758) for those same flows

This would leave only the four genuinely supported flows (Authorize, PSync, Capture, Void) advertised through traits and fully implemented via macros.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 448e2a8 and 7850134.

📒 Files selected for processing (9)
  • backend/connector-integration/src/connectors.rs (1 hunks)
  • backend/connector-integration/src/connectors/peachpayments.rs (1 hunks)
  • backend/connector-integration/src/types.rs (2 hunks)
  • backend/domain_types/src/connector_types.rs (2 hunks)
  • backend/domain_types/src/types.rs (1 hunks)
  • backend/grpc-api-types/proto/payment.proto (1 hunks)
  • config/development.toml (1 hunks)
  • config/production.toml (1 hunks)
  • config/sandbox.toml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • config/development.toml
  • backend/domain_types/src/connector_types.rs
  • config/sandbox.toml
  • backend/connector-integration/src/types.rs
  • config/production.toml
  • backend/connector-integration/src/connectors.rs
🧰 Additional context used
🧠 Learnings (12)
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/types.rs : Update convert_connector to map to the new connector

Applied to files:

  • backend/domain_types/src/types.rs
📚 Learning: 2025-09-24T10:18:33.115Z
Learnt from: Anurag-05-prog
PR: juspay/connector-service#188
File: backend/connector-integration/src/connectors/peachpayments/transformers.rs:50-56
Timestamp: 2025-09-24T10:18:33.115Z
Learning: In Peach Payments connector API (backend/connector-integration/src/connectors/peachpayments/transformers.rs), the authorize request struct uses the field "charge_method" as expected by the Peach Payments API, not "paymentType" or other variations.

Applied to files:

  • backend/domain_types/src/types.rs
  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-09-24T08:45:31.195Z
Learnt from: Anurag-05-prog
PR: juspay/connector-service#188
File: backend/connector-integration/src/connectors/peachpayments.rs:306-315
Timestamp: 2025-09-24T08:45:31.195Z
Learning: In Peachpayments connector (backend/connector-integration/src/connectors/peachpayments.rs), the connector_transaction_id field has different types across flows: PaymentVoidData uses String directly, while PaymentsCaptureData uses ResponseId enum that requires pattern matching or get_connector_transaction_id() method.

Applied to files:

  • backend/domain_types/src/types.rs
  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : For every supported flow, use macros::macro_connector_implementation! to wire ConnectorIntegrationV2, specifying defaults, request/response types, headers, URL, and other flow-specific functions

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Use macros::create_all_prerequisites! to declare connector struct, supported API flows, optional amount converters, and shared member_functions

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Create end-to-end tests per connector in backend/grpc-server/tests/<connector>_payment_flows_test.rs

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-09-15T06:56:22.535Z
Learnt from: Shubhodip900
PR: juspay/connector-service#172
File: backend/connector-integration/src/connectors/trustpay.rs:747-762
Timestamp: 2025-09-15T06:56:22.535Z
Learning: In Trustpay connector (backend/connector-integration/src/connectors/trustpay.rs), the refund_connector_metadata field has different data formats in different contexts: RSync expects it to be already parsed as JSON Value (accessing directly with .get()), while other refund flows expect it to be a JSON string that needs serde_json::from_str() parsing. The extract_payment_method_from_refund_metadata helper is designed for the latter case and should not be used in RSync.

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Implement empty marker traits for each supported flow (e.g., PaymentAuthorizeV2, PaymentSyncV2, PaymentCapture)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/!(mod).rs : Provide explicit Not Implemented errors for unsupported payment methods or types when matching over payment_methods/payment_method_types

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Create reusable utility functions for request construction (email, address, return URL, connector transaction IDs)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Map response_transaction_id and redirect_urls correctly into RouterData fields

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/connector-integration/src/connectors/*/transformers.rs : Persist connector identifiers in response handling (connector_transaction_id, reference_id, mandate_id)

Applied to files:

  • backend/connector-integration/src/connectors/peachpayments.rs
🧬 Code graph analysis (1)
backend/connector-integration/src/connectors/peachpayments.rs (6)
backend/connector-integration/src/connectors/macros.rs (2)
  • router_data (94-105)
  • request_body (66-75)
backend/domain_types/src/connector_types.rs (3)
  • get_connector_transaction_id (275-284)
  • get_connector_transaction_id (1118-1128)
  • get_connector_transaction_id (1890-1899)
backend/common_utils/src/request.rs (2)
  • headers (164-167)
  • header (159-162)
backend/domain_types/src/types.rs (4)
  • connectors (147-147)
  • connectors (151-153)
  • connectors (157-159)
  • connectors (163-165)
backend/connector-integration/src/connectors/peachpayments/transformers.rs (10)
  • try_from (30-36)
  • try_from (305-392)
  • try_from (411-432)
  • try_from (443-452)
  • try_from (602-655)
  • try_from (674-693)
  • try_from (700-745)
  • try_from (757-805)
  • try_from (817-865)
  • try_from (879-884)
backend/common_utils/src/pii.rs (1)
  • expose (40-42)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Analyze (rust)
  • GitHub Check: Run Tests
🔇 Additional comments (8)
backend/domain_types/src/types.rs (1)

127-127: Config slot for Peachpayments looks good.

Thanks for wiring the connector params; this keeps the configuration API aligned with the new integration.

backend/grpc-api-types/proto/payment.proto (1)

459-459: LGTM! Clean enum addition.

The new PEACHPAYMENTS connector enum value follows the established pattern and sequential numbering.

backend/connector-integration/src/connectors/peachpayments.rs (6)

152-212: LGTM! Macro scaffolding follows established patterns.

The create_all_prerequisites! macro correctly declares the connector with four supported flows (Authorize, PSync, Capture, Void) and provides standard helper functions for headers and base URLs.


214-240: LGTM! Authorize flow implementation is correct.

The macro implementation properly wires the Authorize flow with appropriate request/response types, HTTP method, and URL endpoint.


242-276: LGTM! PSync flow correctly extracts transaction ID.

The implementation properly uses get_connector_transaction_id() to extract the raw ID from the ResponseId enum before constructing the URL path.


278-313: LGTM! Capture flow implementation is correct.

Properly extracts the connector transaction ID and constructs the URL with the /confirm endpoint.


315-346: LGTM! Void flow correctly handles String-typed transaction ID.

The implementation correctly uses the connector_transaction_id field directly as a String reference, which is appropriate for PaymentVoidData. Based on learnings, this field has different types across flows (String in Void, ResponseId in Capture), and the current handling is correct.


348-408: LGTM! ConnectorCommon implementation is well-structured.

The implementation correctly:

  • Returns minor currency unit (cents) with helpful documentation
  • Builds three connector-specific auth headers
  • Properly deserializes and maps error responses

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (6)
backend/grpc-server/tests/peachpayments_payment_flows_test.rs (6)

107-115: Don’t hardcode card_network = 1.

This is brittle and may not match enum mapping across versions. Leave it None and let the backend infer from PAN.

Apply this diff:

-        card_network: Some(1),
+        card_network: None,

92-101: Make transaction ID extraction safer and more descriptive.

Avoid unwrap; improve error messages and handle unexpected variants defensively.

Apply this diff:

 fn extract_transaction_id(response: &PaymentServiceAuthorizeResponse) -> String {
-    match &response.transaction_id {
-        Some(id) => match id.id_type.as_ref().unwrap() {
-            IdType::Id(id) => id.clone(),
-            _ => panic!("Expected connector transaction ID"),
-        },
-        None => panic!("Resource ID is None"),
-    }
+    let id = response
+        .transaction_id
+        .as_ref()
+        .expect("authorize response must include transaction_id");
+    match id.id_type.as_ref().expect("transaction_id.id_type missing") {
+        IdType::Id(s) => s.clone(),
+        other => panic!("unexpected id_type variant in transaction_id: {:?}", other),
+    }
 }

237-239: Replace fixed sleeps and strict preconditions with polling to target statuses.

Static sleeps (4s/12s) and strict Authorized-only check before void can cause flakes. Poll PSync until the target status or timeout, then proceed.

Here’s a minimal helper and usage sketch:

@@
 #[tokio::test]
 async fn test_payment_authorization_manual_capture() {
     grpc_test!(client, PaymentServiceClient<Channel>, {
-        // Add delay of 4 seconds
-        tokio::time::sleep(std::time::Duration::from_secs(4)).await;
+        // No fixed sleep; we will poll when needed.
@@
-        // Verify payment status
-        assert!(
-            auth_response.status == i32::from(PaymentStatus::AuthenticationPending)
-                || auth_response.status == i32::from(PaymentStatus::Pending)
-                || auth_response.status == i32::from(PaymentStatus::Authorized),
-            "Payment should be in AuthenticationPending or Pending state"
-        );
+        // Accept initial statuses and proceed.
+        assert!(
+            [PaymentStatus::AuthenticationPending, PaymentStatus::Pending, PaymentStatus::Authorized]
+                .map(i32::from)
+                .contains(&auth_response.status),
+            "Payment should be in AuthenticationPending | Pending | Authorized"
+        );
@@
-        // Create capture request
-        let capture_request = create_payment_capture_request(&transaction_id);
+        // Optional: wait until Authorized before capture (max ~30s).
+        // let _ = wait_until_status(&mut client, &transaction_id, &[PaymentStatus::Authorized], 30).await;
+        let capture_request = create_payment_capture_request(&transaction_id);

Add this helper near other helpers:

async fn wait_until_status(
    client: &mut PaymentServiceClient<Channel>,
    transaction_id: &str,
    targets: &[PaymentStatus],
    timeout_secs: u64,
) -> PaymentStatus {
    let start = std::time::Instant::now();
    loop {
        let req = Request::new(create_payment_sync_request(transaction_id));
        let mut req = req;
        add_peachpayments_metadata(&mut req);
        let resp = client.get(req).await.expect("sync failed").into_inner();
        if targets.iter().map(i32::from).any(|t| t == resp.status) {
            return PaymentStatus::from_i32(resp.status).unwrap();
        }
        if start.elapsed().as_secs() >= timeout_secs {
            panic!("timeout waiting for {:?}, got {:?}", targets, resp.status);
        }
        tokio::time::sleep(std::time::Duration::from_secs(2)).await;
    }
}

Apply similarly in test_payment_void: remove the 12s sleep and replace the strict Authorized check with a poll to Authorized before sending void.

Also applies to: 291-293, 254-267, 308-315


166-180: Sync request: align optional fields.

For PSync many connectors ignore amount/currency; passing mismatched values can confuse audits. After unifying currency, consider omitting amount or ensuring it matches the original.

If optional in proto, set amount to 0 and leave capture_method/currency None, or keep them consistent with authorize. Based on learnings.


6-6: Remove unused imports.

grpc_server::{app, configs} appear unused in this file.

Apply this diff:

-use grpc_server::{app, configs};
+// use grpc_server::{app, configs};

Or remove entirely.


233-285: Add at least one failure-path E2E.

Per our test guidelines, include a negative case (e.g., bad CVC or invalid API key) asserting an error status and connector error mapping. This improves coverage for error handling.

I can draft a minimal negative test (e.g., wrong CVC leading to failure) if you confirm the expected Peachpayments error code. Based on learnings.

Also applies to: 287-355

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7850134 and da3ae99.

📒 Files selected for processing (1)
  • backend/grpc-server/tests/peachpayments_payment_flows_test.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Create end-to-end tests per connector in backend/grpc-server/tests/<connector>_payment_flows_test.rs

Applied to files:

  • backend/grpc-server/tests/peachpayments_payment_flows_test.rs
📚 Learning: 2025-08-29T07:13:53.922Z
Learnt from: CR
PR: juspay/connector-service#0
File: memory-bank/coderabbit/coderabbit_guidelines.md:0-0
Timestamp: 2025-08-29T07:13:53.922Z
Learning: Applies to memory-bank/coderabbit/backend/grpc-server/tests/*_payment_flows_test.rs : Write E2E tests covering all supported payment flows, including success and failure paths

Applied to files:

  • backend/grpc-server/tests/peachpayments_payment_flows_test.rs
📚 Learning: 2025-09-24T08:45:31.195Z
Learnt from: Anurag-05-prog
PR: juspay/connector-service#188
File: backend/connector-integration/src/connectors/peachpayments.rs:306-315
Timestamp: 2025-09-24T08:45:31.195Z
Learning: In Peachpayments connector (backend/connector-integration/src/connectors/peachpayments.rs), the connector_transaction_id field has different types across flows: PaymentVoidData uses String directly, while PaymentsCaptureData uses ResponseId enum that requires pattern matching or get_connector_transaction_id() method.

Applied to files:

  • backend/grpc-server/tests/peachpayments_payment_flows_test.rs
🧬 Code graph analysis (1)
backend/grpc-server/tests/peachpayments_payment_flows_test.rs (3)
backend/grpc-server/src/app.rs (1)
  • grpc_server (172-227)
backend/grpc-server/src/server/health_check.rs (1)
  • check (8-20)
backend/grpc-server/src/server/payments.rs (3)
  • authorize (1317-1431)
  • capture (1931-1948)
  • void (1652-1669)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (1)
backend/grpc-server/tests/peachpayments_payment_flows_test.rs (1)

268-271: Comment mentions terminal_id but header isn’t explicit.

The comment says “include the terminal_id”, but headers set x-key1 and metadata.tid. If x-key1 is indeed terminal_id, clarify the comment; else add the correct header.

Apply this diff if x-key1 is terminal id:

-        // Add metadata headers for capture request - make sure they include the terminal_id
+        // Add metadata headers for capture request (x-key1 is terminal_id)

Otherwise, add the proper header in add_peachpayments_metadata. Based on learnings.

Comment on lines +43 to +45
const TEST_CARD_EXP_MONTH: &str = "10";
const TEST_CARD_EXP_YEAR: &str = "25";
const TEST_CARD_CVC: &str = "123";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid near-expiry test card; update to a future date.

"10/25" will soon expire, making tests flaky after October 2025. Use a later expiry.

Apply this diff:

-const TEST_CARD_EXP_MONTH: &str = "10";
-const TEST_CARD_EXP_YEAR: &str = "25";
+const TEST_CARD_EXP_MONTH: &str = "12";
+const TEST_CARD_EXP_YEAR: &str = "30";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const TEST_CARD_EXP_MONTH: &str = "10";
const TEST_CARD_EXP_YEAR: &str = "25";
const TEST_CARD_CVC: &str = "123";
const TEST_CARD_EXP_MONTH: &str = "12";
const TEST_CARD_EXP_YEAR: &str = "30";
const TEST_CARD_CVC: &str = "123";
🤖 Prompt for AI Agents
In backend/grpc-server/tests/peachpayments_payment_flows_test.rs around lines 43
to 45, the test card expiry is set to "10/25" which will become stale; update
the constants TEST_CARD_EXP_MONTH and TEST_CARD_EXP_YEAR to a later future date
(for example month "12" and year "30" or any year well beyond current year) so
tests remain stable, and run the test suite to confirm no failures.

Comment on lines +57 to +90
// Helper function to add Peachpayments metadata headers to a request
fn add_peachpayments_metadata<T>(request: &mut Request<T>) {
// Get API credentials from environment variables - throw error if not set
let api_key = env::var(PEACHPAYMENTS_API_KEY_ENV)
.expect("TEST_PEACHPAYMENTS_API_KEY environment variable is required");
let key1 = env::var(PEACHPAYMENTS_KEY1_ENV)
.expect("TEST_PEACHPAYMENTS_KEY1 environment variable is required");

request.metadata_mut().append(
"x-connector",
CONNECTOR_NAME.parse().expect("Failed to parse x-connector"),
);
request
.metadata_mut()
.append("x-auth", AUTH_TYPE.parse().expect("Failed to parse x-auth"));

request.metadata_mut().append(
"x-api-key",
api_key.parse().expect("Failed to parse x-api-key"),
);
request
.metadata_mut()
.append("x-key1", key1.parse().expect("Failed to parse x-key1"));
request.metadata_mut().append(
"x-merchant-id",
MERCHANT_ID.parse().expect("Failed to parse x-merchant-id"),
);
request.metadata_mut().append(
"x-request-id",
format!("test_request_{}", get_timestamp())
.parse()
.expect("Failed to parse x-request-id"),
);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don’t hardcode merchant ID; use env and avoid duplicate headers.

"x-merchant-id" uses a hardcoded MERCHANT_ID while metadata uses TEST_PEACHPAYMENTS_MERCHANT_ID. Read merchant ID from the same env var and use insert (not append) for headers to prevent duplicates.

Apply this diff:

--- a/backend/grpc-server/tests/peachpayments_payment_flows_test.rs
+++ b/backend/grpc-server/tests/peachpayments_payment_flows_test.rs
@@
-// Constants for Peachpayments connector
-const CONNECTOR_NAME: &str = "peachpayments";
-const AUTH_TYPE: &str = "body-key";
-const MERCHANT_ID: &str = "merchant_1758520172";
+// Constants for Peachpayments connector
+const CONNECTOR_NAME: &str = "peachpayments";
+const AUTH_TYPE: &str = "body-key";
@@
 fn add_peachpayments_metadata<T>(request: &mut Request<T>) {
@@
-    request.metadata_mut().append(
-        "x-connector",
-        CONNECTOR_NAME.parse().expect("Failed to parse x-connector"),
-    );
-    request
-        .metadata_mut()
-        .append("x-auth", AUTH_TYPE.parse().expect("Failed to parse x-auth"));
+    request.metadata_mut().insert(
+        "x-connector",
+        CONNECTOR_NAME.parse().expect("Failed to parse x-connector"),
+    );
+    request
+        .metadata_mut()
+        .insert("x-auth", AUTH_TYPE.parse().expect("Failed to parse x-auth"));
@@
-    request.metadata_mut().append(
-        "x-api-key",
-        api_key.parse().expect("Failed to parse x-api-key"),
-    );
-    request
-        .metadata_mut()
-        .append("x-key1", key1.parse().expect("Failed to parse x-key1"));
-    request.metadata_mut().append(
-        "x-merchant-id",
-        MERCHANT_ID.parse().expect("Failed to parse x-merchant-id"),
-    );
-    request.metadata_mut().append(
-        "x-request-id",
-        format!("test_request_{}", get_timestamp())
-            .parse()
-            .expect("Failed to parse x-request-id"),
-    );
+    request.metadata_mut().insert(
+        "x-api-key",
+        api_key.parse().expect("Failed to parse x-api-key"),
+    );
+    request
+        .metadata_mut()
+        .insert("x-key1", key1.parse().expect("Failed to parse x-key1"));
+    let merchant_id = env::var("TEST_PEACHPAYMENTS_MERCHANT_ID")
+        .expect("TEST_PEACHPAYMENTS_MERCHANT_ID environment variable is required");
+    request.metadata_mut().insert(
+        "x-merchant-id",
+        merchant_id.parse().expect("Failed to parse x-merchant-id"),
+    );
+    request.metadata_mut().insert(
+        "x-request-id",
+        format!("test_request_{}", get_timestamp())
+            .parse()
+            .expect("Failed to parse x-request-id"),
+    );

Also remove the now-unused MERCHANT_ID constant.

Also applies to: 30-34

🤖 Prompt for AI Agents
In backend/grpc-server/tests/peachpayments_payment_flows_test.rs around lines 57
to 90, the helper currently appends a hardcoded MERCHANT_ID header and uses
append for headers which can create duplicates; change it to read the merchant
id from the TEST_PEACHPAYMENTS_MERCHANT_ID environment variable (using env::var
and expect like the other creds) and use request.metadata_mut().insert(...)
instead of append for the x-merchant-id (and any other headers that should not
duplicate), and remove the now-unused MERCHANT_ID constant definition at lines
30-34.

Comment on lines +178 to +179
currency: i32::from(Currency::Eur),
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Fix currency mismatches across flows (USD/EUR/ZAR).

Authorize/Capture use USD but Sync uses EUR and Void uses ZAR. This can cause connector-side validation failures or confusing assertions. Unify to a single currency (pick the one configured for the test merchant; using USD below for consistency with authorize/capture).

Apply this diff:

--- a/backend/grpc-server/tests/peachpayments_payment_flows_test.rs
+++ b/backend/grpc-server/tests/peachpayments_payment_flows_test.rs
@@
-        currency: i32::from(Currency::Eur),
+        currency: i32::from(Currency::Usd),
@@
-        currency: Some(i32::from(Currency::Zar)),
+        currency: Some(i32::from(Currency::Usd)),

If your Peachpayments sandbox requires ZAR, set all three places to ZAR instead.

Also applies to: 210-211


I'll verify the currency mismatch claims by examining the test file and Peachpayments connector implementation.


🏁 Script executed:

#!/bin/bash
# Examine the peachpayments test file to see all currency usages
echo "=== Currency usages in peachpayments_payment_flows_test.rs ==="
rg -n "currency" backend/grpc-server/tests/peachpayments_payment_flows_test.rs -A 1 -B 1

Length of output: 521


🏁 Script executed:

#!/bin/bash
# Check the Peachpayments connector implementation for currency handling
echo "=== Peachpayments connector currency references ==="
rg -n "Currency" backend/connector-integration/src/connectors/peachpayments.rs -C 2

Length of output: 399


🏁 Script executed:

#!/bin/bash
# Look for any merchant or test configuration that specifies currency
echo "=== Test setup and merchant configuration ==="
rg -n "MERCHANT_ID\|merchant.*currency\|test.*currency" backend/grpc-server/tests/peachpayments_payment_flows_test.rs -B 2 -A 2

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Check lines 178-179 and 210-211 specifically
echo "=== Lines 178-179 ==="
sed -n '175,182p' backend/grpc-server/tests/peachpayments_payment_flows_test.rs
echo ""
echo "=== Lines 207-214 ==="
sed -n '207,214p' backend/grpc-server/tests/peachpayments_payment_flows_test.rs

Length of output: 410


I need to check the function names and context to understand if these currency differences are intentional:


🏁 Script executed:

#!/bin/bash
# Get function names and context for each currency definition
echo "=== Function context for line 145 (USD authorize) ==="
sed -n '130,150p' backend/grpc-server/tests/peachpayments_payment_flows_test.rs

echo ""
echo "=== Function context for line 178 (EUR sync) ==="
sed -n '170,185p' backend/grpc-server/tests/peachpayments_payment_flows_test.rs

echo ""
echo "=== Function context for line 189 (USD capture) ==="
sed -n '180,195p' backend/grpc-server/tests/peachpayments_payment_flows_test.rs

echo ""
echo "=== Function context for line 210 (ZAR void) ==="
sed -n '200,215p' backend/grpc-server/tests/peachpayments_payment_flows_test.rs

Length of output: 2432


🏁 Script executed:

#!/bin/bash
# Check test functions that use these payment requests to understand flow
echo "=== Test functions using these requests ==="
rg -n "fn test_.*peachpayments\|create_payment_authorize\|create_payment_sync\|create_payment_capture\|create_payment_void" backend/grpc-server/tests/peachpayments_payment_flows_test.rs -A 2

Length of output: 43


🏁 Script executed:

#!/bin/bash
# Check if there are any comments explaining currency choices
echo "=== Comments near currency definitions ==="
sed -n '140,220p' backend/grpc-server/tests/peachpayments_payment_flows_test.rs | grep -n "//\|/\*" -A 1 -B 1

Length of output: 793


Fix currency mismatches across payment flow functions (USD/EUR/ZAR).

The mismatch is confirmed across the payment flow helpers:

  • Authorize: USD (line 145)
  • Sync: EUR (line 178)
  • Capture: USD (line 189)
  • Void: ZAR (line 210)

Different currencies across connected payment operations can cause connector validation failures or confusing test failures. Unify to one currency across all helpers.

Apply diffs at lines 178 and 210:

--- a/backend/grpc-server/tests/peachpayments_payment_flows_test.rs
+++ b/backend/grpc-server/tests/peachpayments_payment_flows_test.rs
@@ Line 178 @@
-        currency: i32::from(Currency::Eur),
+        currency: i32::from(Currency::Usd),

@@ Line 210 @@
-        currency: Some(i32::from(Currency::Zar)),
+        currency: Some(i32::from(Currency::Usd)),

If your Peachpayments test merchant requires a different currency, set all four locations (lines 145, 178, 189, 210) to that currency instead.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
currency: i32::from(Currency::Eur),
}
currency: i32::from(Currency::Usd),
}
🤖 Prompt for AI Agents
In backend/grpc-server/tests/peachpayments_payment_flows_test.rs around lines
145, 178, 189 and 210, the test helpers use inconsistent currencies (Authorize:
USD at 145, Sync: EUR at 178, Capture: USD at 189, Void: ZAR at 210); update the
currency values at lines 178 and 210 to match the currency used at line 145 (or
choose the Peachpayments test merchant's required currency and set all four
locations to that same currency) so all payment flow helper functions use the
same Currency enum value.

Comment on lines +254 to +260
// Verify payment status
assert!(
auth_response.status == i32::from(PaymentStatus::AuthenticationPending)
|| auth_response.status == i32::from(PaymentStatus::Pending)
|| auth_response.status == i32::from(PaymentStatus::Authorized),
"Payment should be in AuthenticationPending or Pending state"
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Assertion message is misleading.

Message omits Authorized though it’s allowed. Update the text.

Apply this diff:

-            "Payment should be in AuthenticationPending or Pending state"
+            "Payment should be in AuthenticationPending | Pending | Authorized"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Verify payment status
assert!(
auth_response.status == i32::from(PaymentStatus::AuthenticationPending)
|| auth_response.status == i32::from(PaymentStatus::Pending)
|| auth_response.status == i32::from(PaymentStatus::Authorized),
"Payment should be in AuthenticationPending or Pending state"
);
// Verify payment status
assert!(
auth_response.status == i32::from(PaymentStatus::AuthenticationPending)
|| auth_response.status == i32::from(PaymentStatus::Pending)
|| auth_response.status == i32::from(PaymentStatus::Authorized),
"Payment should be in AuthenticationPending | Pending | Authorized"
);
🤖 Prompt for AI Agents
In backend/grpc-server/tests/peachpayments_payment_flows_test.rs around lines
254 to 260, the assertion message says "Payment should be in
AuthenticationPending or Pending state" but the condition also allows
Authorized; update the assertion message to list all allowed states
(AuthenticationPending, Pending, or Authorized) so it accurately reflects the
check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

coderabbit-ai-review Trigger CodeRabbit review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants