Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(connector): [PAYSTACK] EFT Payment Flows #7286

Open
wants to merge 3 commits into
base: eft_payment_method
Choose a base branch
from

Conversation

ImSagnik007
Copy link
Contributor

@ImSagnik007 ImSagnik007 commented Feb 17, 2025

Type of Change

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

Description

Paystack EFT flow (Payments, PSync, Refunds, RSync, Webhooks).

Additional Changes

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

Motivation and Context

How did you test it?

  1. Merchant Account Create:
curl --location 'http://localhost:8080/accounts' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data-raw '{
  "merchant_id": "merchant_1739960795",
  "locker_id": "m0010",
  "merchant_name": "NewAge Retailer",
  "merchant_details": {
    "primary_contact_person": "John Test",
    "primary_email": "[email protected]",
    "primary_phone": "sunt laborum",
    "secondary_contact_person": "John Test2",
    "secondary_email": "[email protected]",
    "secondary_phone": "cillum do dolor id",
    "website": "https://www.example.com",
    "about_business": "Online Retail with a wide selection of organic products for North America",
    "address": {
      "line1": "1467",
      "line2": "Harrison Street",
      "line3": "Harrison Street",
      "city": "San Fransico",
      "state": "California",
      "zip": "94122",
      "country": "US"
    }
  },
  "return_url": "https://google.com/success",
  "webhook_details": {
    "webhook_version": "1.0.1",
    "webhook_username": "ekart_retail",
    "webhook_password": "password_ekart@123",
    "payment_created_enabled": true,
    "payment_succeeded_enabled": true,
    "payment_failed_enabled": true
  },
  "sub_merchants_enabled": false,
  "metadata": {
    "city": "NY",
    "unit": "245"
  },
  "primary_business_details": [
    {
      "country": "US",
      "business": "food"
    }
  ]
}'
  1. API Key Create:
curl --location 'http://localhost:8080/api_keys/merchant_1739898797' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data '{
  "name": "API Key 1",
  "description": null,
  "expiration": "2025-09-23T01:02:03.000Z"
}'
  1. Paystack Connector Create:
curl --location 'http://localhost:8080/account/merchant_1739898797/connectors?=' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data '{
    "connector_type": "payment_processor",
    "connector_name": "paystack",
    "connector_account_details": {
        "auth_type": "HeaderKey",
        "api_key": "abc"
    },
    "test_mode": false,
    "disabled": false,
    "payment_methods_enabled": [
        {
                "payment_method": "bank_redirect",
                "payment_method_types": [
                    {
                        "payment_method_type": "eft",
                        "payment_experience": "redirect_to_url",
                        "card_networks": null,
                        "accepted_currencies": null,
                        "accepted_countries": null,
                        "minimum_amount": 0,
                        "maximum_amount": 68607706,
                        "recurring_enabled": true,
                        "installment_payment_enabled": false
                    }
                ]
            }
    ],
    "connector_webhook_details": {
        "merchant_secret": "abc",
        "additional_secret": null
    }
}'
  1. Payments Create:
    Request:
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_ykM0z3Y0k65EtZIce9BsbJXPtoq7KzcAWsLZUS3SIT13cdYEOQQ4mMkb4UMB5Oyd' \
--data-raw '{
  "amount": 6540,
  "currency": "ZAR",
  "confirm": true,
  "amount_to_capture": 6540,
  "customer_id": "StripbmnxeCustomer",
  "email": "[email protected]",
  "description": "Its my first payment request",
  "return_url": "https://google.com",
  "payment_method": "bank_redirect",
  "payment_method_type": "eft",
  "payment_method_data": {
    "bank_redirect": {
      "eft": {
        "provider": "ozow"
      }
    }
  }
}'

Response:

{
    "payment_id": "pay_kQrdGr1rVMmwEKYXorLM",
    "merchant_id": "merchant_1739898797",
    "status": "requires_customer_action",
    "amount": 6540,
    "net_amount": 6540,
    "shipping_cost": null,
    "amount_capturable": 6540,
    "amount_received": null,
    "connector": "paystack",
    "client_secret": "pay_kQrdGr1rVMmwEKYXorLM_secret_U7lStVK9TuKNY4l0mxmc",
    "created": "2025-02-19T10:32:31.775Z",
    "currency": "ZAR",
    "customer_id": "StripbmnxeCustomer",
    "customer": {
        "id": "StripbmnxeCustomer",
        "name": null,
        "email": "[email protected]",
        "phone": null,
        "phone_country_code": null
    },
    "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": null,
    "payment_method": "bank_redirect",
    "payment_method_data": {
        "bank_redirect": {
            "type": "BankRedirectResponse",
            "bank_name": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": null,
    "billing": null,
    "order_details": null,
    "email": "[email protected]",
    "name": null,
    "phone": null,
    "return_url": "https://google.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": {
        "type": "redirect_to_url",
        "redirect_to_url": "http://localhost:8080/payments/redirect/pay_kQrdGr1rVMmwEKYXorLM/merchant_1739898797/pay_kQrdGr1rVMmwEKYXorLM_1"
    },
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "eft",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": {
        "customer_id": "StripbmnxeCustomer",
        "created_at": 1739961151,
        "expires": 1739964751,
        "secret": "epk_09592792e8504aa3a943feff38c3e3e2"
    },
    "manual_retry_allowed": null,
    "connector_transaction_id": "sug0jyf5kbbbpe5",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_z5wMP3CJUUrMDF5CBGl9",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_Ux3UO8AL0iD9BlzLSE83",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-02-19T10:47:31.774Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2025-02-19T10:32:32.739Z",
    "split_payments": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null
}
  1. Payments Retrieve
    Request:
curl --location 'http://localhost:8080/payments/pay_kWVz157PfvGL9GyAiTnI?force_sync=true' \
--header 'Accept: application/json' \
--header 'api-key: dev_ykM0z3Y0k65EtZIce9BsbJXPtoq7KzcAWsLZUS3SIT13cdYEOQQ4mMkb4UMB5Oyd' \
--data ''

Response: Same as payments response>

  1. Refunds Create
    Request:
curl --location 'http://localhost:8080/refunds' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_ykM0z3Y0k65EtZIce9BsbJXPtoq7KzcAWsLZUS3SIT13cdYEOQQ4mMkb4UMB5Oyd' \
--data '{
  "payment_id": "pay_6Ww3WmcWCT8ni7O5K5gV",
  "amount": 1000,
  "reason": "Customer returned product",
  "refund_type": "instant",
  "metadata": {
    "udf1": "value1",
    "new_customer": "true",
    "login_date": "2019-09-10T10:11:12Z"
  }
}'

Response:

{
    "refund_id": "ref_XSsCj6O6bujAZypJAFJk",
    "payment_id": "pay_6Ww3WmcWCT8ni7O5K5gV",
    "amount": 1000,
    "currency": "ZAR",
    "status": "succeeded",
    "reason": "Customer returned product",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    },
    "error_message": null,
    "error_code": null,
    "unified_code": null,
    "unified_message": null,
    "created_at": "2025-02-19T10:31:32.658Z",
    "updated_at": "2025-02-19T10:31:34.094Z",
    "connector": "paystack",
    "profile_id": "pro_z5wMP3CJUUrMDF5CBGl9",
    "merchant_connector_id": "mca_Ux3UO8AL0iD9BlzLSE83",
    "split_refunds": null
}
  1. Refunds Retrieve
    Request:
curl --location 'http://localhost:8080/refunds/ref_XSsCj6O6bujAZypJAFJk' \
--header 'Accept: application/json' \
--header 'api-key: dev_ZgTXlFsnanc0o4AW2Ag32dJQsA1rAvU1prQVsIE0JbUjPv7g65ZU5pO7MyiPLL5J'

Response: Same as Refunds response.

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

@ImSagnik007 ImSagnik007 added the A-connector-integration Area: Connector integration label Feb 17, 2025
@ImSagnik007 ImSagnik007 self-assigned this Feb 17, 2025
@ImSagnik007 ImSagnik007 requested review from a team as code owners February 17, 2025 11:30
Copy link

semanticdiff-com bot commented Feb 17, 2025

Review changes with  SemanticDiff

Changed Files
File Status
  crates/router/src/types/api.rs  75% smaller
  crates/hyperswitch_connectors/src/connectors/paystack/transformers.rs  24% smaller
  api-reference-v2/openapi_spec.json  0% smaller
  api-reference/openapi_spec.json  0% smaller
  crates/hyperswitch_connectors/src/connectors/paystack.rs  0% smaller

@jarnura jarnura changed the base branch from main to paystack_template February 17, 2025 11:36
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Feb 17, 2025
@Anurag-05-prog Anurag-05-prog linked an issue Feb 18, 2025 that may be closed by this pull request
5 tasks
@hyperswitch-bot hyperswitch-bot bot removed the M-api-contract-changes Metadata: This PR involves API contract changes label Feb 18, 2025
@ImSagnik007 ImSagnik007 changed the base branch from paystack_template to main February 18, 2025 19:32
@ImSagnik007 ImSagnik007 changed the base branch from main to paystack_template February 18, 2025 19:33
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Feb 18, 2025
@ImSagnik007 ImSagnik007 changed the base branch from paystack_template to eft_payment_method February 18, 2025 20:36
@hyperswitch-bot hyperswitch-bot bot removed the M-api-contract-changes Metadata: This PR involves API contract changes label Feb 18, 2025
@ImSagnik007 ImSagnik007 changed the title feat(connector): [PAYSTACK] Payments and PSync flow for EFT feat(connector): [PAYSTACK] EFT Payment Flows Feb 18, 2025
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Feb 18, 2025
@hyperswitch-bot hyperswitch-bot bot added M-api-contract-changes Metadata: This PR involves API contract changes and removed M-api-contract-changes Metadata: This PR involves API contract changes labels Feb 19, 2025
@@ -109,7 +109,7 @@ pub enum RoutableConnectors {
Payme,
Payone,
Paypal,
// Paystack,
Paystack,
Copy link
Member

Choose a reason for hiding this comment

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

we can do these in template itself

@@ -378,7 +378,7 @@ impl ConnectorConfig {
Connector::Payme => Ok(connector_data.payme),
Connector::Payone => Err("Use get_payout_connector_config".to_string()),
Connector::Paypal => Ok(connector_data.paypal),
// Connector::Paystack => Ok(connector_data.paystack),
Connector::Paystack => Ok(connector_data.paystack),
Copy link
Member

Choose a reason for hiding this comment

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

we can do these in template PR itself

@hyperswitch-bot hyperswitch-bot bot removed the M-api-contract-changes Metadata: This PR involves API contract changes label Feb 20, 2025
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Feb 20, 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 M-api-contract-changes Metadata: This PR involves API contract changes
Projects
None yet
2 participants