Skip to content

feat(payouts): apple pay decrypt payout#9857

Merged
likhinbopanna merged 5 commits intomainfrom
apple_pay_decrypt_payout
Oct 16, 2025
Merged

feat(payouts): apple pay decrypt payout#9857
likhinbopanna merged 5 commits intomainfrom
apple_pay_decrypt_payout

Conversation

@Sakilmostak
Copy link
Contributor

@Sakilmostak Sakilmostak commented Oct 15, 2025

Type of Change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring
  • Dependency updates
  • Documentation
  • CI/CD

Description

  • Payout is done via Decrypted Token data of Apple pay.
  • The decrypted data is directly collected in the request to initiate payout.
  • Integration is done via Worldpay for the following flow

Additional Changes

  • This PR modifies the API contract
"payout_method_data": {
        "wallet": {
            "apple_pay_decrypt": {
                "dpan": "4444333322221111",
                "expiry_month": "05",
                "expiry_year": "2035",
                "card_holder_name": "John Appleseed"
            }
        }
    },
  • This PR modifies the database schema
  • This PR modifies application configuration/environment variables

Motivation and Context

How did you test it?

Create an MCA with WorldPay for payouts
Do a payout request with apple pay decrypted data:

curl --location '{{baseUrl}}/payouts/create' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: ={{api_key}}' \
--data-raw '{
    "amount": 100,
    "currency": "GBP",
    "customer_id": "payout_customer",
    "email": "payout_customer@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "profile_id": "{{profile_id}}",
    "phone_country_code": "+65",
    "description": "Its my first payout request",
    "payout_type": "wallet",
    "payout_method_data": {
        "wallet": {
            "apple_pay_decrypt": {
                "dpan": "4444333322221111",
                "expiry_month": "05",
                "expiry_year": "2035",
                "card_holder_name": "John Appleseed"
            }
        }
    },
    "entity_type": "Individual",
    "recurring": true,
    "metadata": {
        "ref": "123"
    },
    "auto_fulfill": true,
    "confirm": true
    
}'

response should have status as initiated, below is an example

{
    "payout_id": "payout_EVQi7ysLwVQ7cSuK2POO",
    "merchant_id": "merchant_1760528955",
    "merchant_order_reference_id": null,
    "amount": 100,
    "currency": "GBP",
    "connector": "worldpay",
    "payout_type": "wallet",
    "payout_method_data": {
        "wallet": {
            "email": null,
            "telephone_number": null,
            "paypal_id": null
        }
    },
    "billing": null,
    "auto_fulfill": true,
    "customer_id": "payout_customer",
    "customer": {
        "id": "payout_customer",
        "name": "John Doe",
        "email": "payout_customer@example.com",
        "phone": "999999999",
        "phone_country_code": "+65"
    },
    "client_secret": "payout_payout_EVQi7ysLwVQ7cSuK2POO_secret_6UFSzfVYuJ5GfA9Brxb1",
    "return_url": null,
    "business_country": null,
    "business_label": null,
    "description": "Its my first payout request",
    "entity_type": "Individual",
    "recurring": true,
    "metadata": {
        "ref": "123"
    },
    "merchant_connector_id": "mca_SRDKLfmRXfgKlJgjxE2P",
    "status": "initiated",
    "error_message": null,
    "error_code": null,
    "profile_id": "pro_UE5pBOruekGz1eD2yWxW",
    "created": "2025-10-15T12:05:17.747Z",
    "connector_transaction_id": null,
    "priority": null,
    "payout_link": null,
    "email": "payout_customer@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "phone_country_code": "+65",
    "unified_code": null,
    "unified_message": null,
    "payout_method_id": "pm_s8SUzT8ndfakfZ7Pw0Dn"
}

Checklist

  • I formatted the code cargo +nightly fmt --all
  • I addressed lints thrown by cargo clippy
  • I reviewed the submitted code
  • I added unit tests for my changes where possible

@Sakilmostak Sakilmostak self-assigned this Oct 15, 2025
@Sakilmostak Sakilmostak requested review from a team as code owners October 15, 2025 10:01
@semanticdiff-com
Copy link

semanticdiff-com bot commented Oct 15, 2025

Review changes with  SemanticDiff

Changed Files
File Status
  crates/hyperswitch_connectors/src/default_implementations.rs  26% smaller
  crates/openapi/src/openapi.rs  9% smaller
  crates/openapi/src/openapi_v2.rs  9% smaller
  api-reference/v1/openapi_spec_v1.json  3% smaller
  api-reference/v2/openapi_spec_v2.json  3% smaller
  crates/api_models/src/enums.rs  0% smaller
  crates/api_models/src/payouts.rs  0% smaller
  crates/common_enums/src/connector_enums.rs  0% smaller
  crates/common_utils/src/payout_method_utils.rs  0% smaller
  crates/connector_configs/src/connector.rs  0% smaller
  crates/connector_configs/toml/development.toml Unsupported file format
  crates/connector_configs/toml/production.toml Unsupported file format
  crates/connector_configs/toml/sandbox.toml Unsupported file format
  crates/hyperswitch_connectors/src/connectors/adyen/transformers.rs  0% smaller
  crates/hyperswitch_connectors/src/connectors/paypal/transformers.rs  0% smaller
  crates/hyperswitch_connectors/src/connectors/worldpay.rs  0% smaller
  crates/hyperswitch_connectors/src/connectors/worldpay/payout_requests.rs  0% smaller
  crates/hyperswitch_connectors/src/connectors/worldpay/payout_response.rs  0% smaller
  crates/hyperswitch_connectors/src/connectors/worldpay/payout_transformers.rs  0% smaller
  crates/hyperswitch_connectors/src/utils.rs  0% smaller
  crates/router/src/core/payment_methods/vault.rs  0% smaller
  crates/router/src/types/transformers.rs  0% smaller

@Sakilmostak Sakilmostak added A-connector-integration Area: Connector integration C-feature Category: Feature request or enhancement Payouts Area: Payouts labels Oct 15, 2025
Comment on lines +251 to +263
pub struct ApplePayDecryptAdditionalData {
/// Card expiry month
#[schema(value_type = String, example = "01")]
pub card_exp_month: Secret<String>,

/// Card expiry year
#[schema(value_type = String, example = "2026")]
pub card_exp_year: Secret<String>,

/// Card holder name
#[schema(value_type = String, example = "John Doe")]
pub card_holder_name: Option<Secret<String>>,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need additional details for device bound data? If yes, we can add last4 of DPAN as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will need to confirm with the merchant if it is a requirement for them.

@Sakilmostak Sakilmostak linked an issue Oct 15, 2025 that may be closed by this pull request
kashif-m
kashif-m previously approved these changes Oct 16, 2025
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Oct 16, 2025
#[cfg(feature = "payouts")]
impl CardData for api_models::payouts::ApplePayDecrypt {
fn get_card_expiry_year_2_digit(&self) -> Result<Secret<String>, errors::ConnectorError> {
let binding = self.expiry_month.clone();
Copy link
Contributor

Choose a reason for hiding this comment

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

should we fetch expiry_year ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

raised a corresponding fix in a separate pr to not make this pr stale: #9871
Note: this method is not being used in current implementation

@likhinbopanna likhinbopanna added this pull request to the merge queue Oct 16, 2025
Merged via the queue into main with commit e7dee75 Oct 16, 2025
21 of 25 checks passed
@likhinbopanna likhinbopanna deleted the apple_pay_decrypt_payout branch October 16, 2025 08:06
drdholu pushed a commit to drdholu/hyperswitch that referenced this pull request Oct 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-connector-integration Area: Connector integration C-feature Category: Feature request or enhancement M-api-contract-changes Metadata: This PR involves API contract changes Payouts Area: Payouts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]: [Payouts] apple pay decrypt payout

6 participants