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(core): add bulk tokenization flows #7066

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

kashif-m
Copy link
Contributor

@kashif-m kashif-m commented Jan 20, 2025

Type of Change

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

Description

This PR introduces below changes

  • Exposes two endpoints for
    • Single card tokenization
      • Tokenizing raw card details with the network
      • Tokenizing an existing payment method in HS with the network (card only)
    • Bulk tokenization
      • Tokenizing using raw card details or an existing payment method

More details around the flow is present in #6971

Additional Changes

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

Motivation and Context

This helps merchants to tokenize their customer's payment methods with the card networks. A new payment method entry is created for every card which can be used to perform txns using the network tokens.

How did you test it?

1. Tokenize using raw card details

cURL

curl --location --request POST 'http://localhost:8080/payment_methods/tokenize-card' \
    --header 'Content-Type: application/json' \
    --header 'api-key: test_admin' \
    --data '{
        "card": {
            "raw_card_number": "4761360080000093",
            "card_expiry_month": "01",
            "card_expiry_year": "26",
            "card_cvc": "947"
        },
        "merchant_id": "merchant_1737627877",
        "card_type": "debit",
        "customer": {
            "id": "cus_IoFeOlGhEeD54AbBdvxI"
        }
    }'

Response

{"payment_method_response":{"merchant_id":"merchant_1737627877","customer_id":"cus_IoFeOlGhEeD54AbBdvxI","payment_method_id":"pm_ai4pU6o32LUgRy2kl5hd","payment_method":"card","payment_method_type":null,"card":{"scheme":null,"issuer_country":null,"last4_digits":"0093","expiry_month":"01","expiry_year":"26","card_token":null,"card_holder_name":null,"card_fingerprint":null,"nick_name":null,"card_network":null,"card_isin":"476136","card_issuer":null,"card_type":null,"saved_to_locker":false},"recurring_enabled":true,"installment_payment_enabled":false,"payment_experience":null,"metadata":null,"created":"2025-01-23T10:41:54.753Z","last_used_at":null,"client_secret":null},"customer":{"id":"cus_IoFeOlGhEeD54AbBdvxI","name":"John Nether","email":"[email protected]","phone":"6168205362","phone_country_code":"+1"},"card_tokenized":true,"req":null}
2. Tokenize using existing payment method entry

cURL

curl --location --request POST 'http://localhost:8080/payment_methods/tokenize-card' \
    --header 'Content-Type: application/json' \
    --header 'api-key: test_admin' \
    --data '{
        "payment_method": {
            "payment_method_id": "pm_HHZV9XC6C10jjKGiK8m1",
            "card_cvc": "947"
        },
        "merchant_id": "merchant_1737627877",
        "card_type": "debit",
        "customer": {
            "id": "cus_IoFeOlGhEeD54AbBdvxI"
        }
    }'

Response

{"payment_method_response":{"merchant_id":"merchant_1737627877","customer_id":"cus_IoFeOlGhEeD54AbBdvxI","payment_method_id":"pm_HHZV9XC6C10jjKGiK8m1","payment_method":"card","payment_method_type":null,"card":{"scheme":null,"issuer_country":null,"last4_digits":"0000","expiry_month":"03","expiry_year":"2030","card_token":null,"card_holder_name":"John US","card_fingerprint":null,"nick_name":"JD","card_network":null,"card_isin":"491761","card_issuer":null,"card_type":null,"saved_to_locker":false},"recurring_enabled":true,"installment_payment_enabled":false,"payment_experience":null,"metadata":null,"created":"2025-01-23T10:43:02.151Z","last_used_at":"2025-01-23T10:43:02.151Z","client_secret":"pm_HHZV9XC6C10jjKGiK8m1_secret_SJC4AUiR4HmYzSDOKwPi"},"customer":{"id":"cus_IoFeOlGhEeD54AbBdvxI","name":null,"email":null,"phone":null,"phone_country_code":null},"card_tokenized":true,"req":null}
3. Bulk tokenize

cURL

curl --location --request POST 'http://localhost:8080/payment_methods/tokenize-card-batch' \
    --header 'api-key: test_admin' \
    --form 'merchant_id="merchant_1737627877"' \
    --form 'file=@"/Users/Downloads/tokenization sample - Sheet 1.csv"'

Response

[{"payment_method_response":{"merchant_id":"merchant_1737627877","customer_id":"cus_Hn03n9kbTqUxKZ0nZRVC","payment_method_id":"pm_eBONxbqiaf8T7KkGSlaq","payment_method":"card","payment_method_type":null,"card":{"scheme":null,"issuer_country":null,"last4_digits":"0000","expiry_month":"1","expiry_year":"2026","card_token":null,"card_holder_name":null,"card_fingerprint":null,"nick_name":"real joe","card_network":null,"card_isin":"420000","card_issuer":null,"card_type":null,"saved_to_locker":false},"recurring_enabled":true,"installment_payment_enabled":false,"payment_experience":null,"metadata":null,"created":"2025-01-23T10:24:53.998Z","last_used_at":null,"client_secret":null},"customer":{"id":"cus_Hn03n9kbTqUxKZ0nZRVC","name":"Max Mustermann","email":"[email protected]","phone":null,"phone_country_code":null},"card_tokenized":true,"req":null},{"payment_method_response":{"merchant_id":"merchant_1737627877","customer_id":"cus_OWDUMC1QBmsTeImT9xCs","payment_method_id":"pm_nRtoCkil21RaGNJulP2L","payment_method":"card","payment_method_type":null,"card":{"scheme":null,"issuer_country":null,"last4_digits":"0000","expiry_month":"1","expiry_year":"2026","card_token":null,"card_holder_name":null,"card_fingerprint":null,"nick_name":"real joe","card_network":null,"card_isin":"420000","card_issuer":null,"card_type":null,"saved_to_locker":false},"recurring_enabled":true,"installment_payment_enabled":false,"payment_experience":null,"metadata":null,"created":"2025-01-23T10:24:53.998Z","last_used_at":null,"client_secret":null},"customer":{"id":"cus_OWDUMC1QBmsTeImT9xCs","name":"Max Mustermann","email":"[email protected]","phone":null,"phone_country_code":null},"card_tokenized":true,"req":null},{"payment_method_response":{"merchant_id":"merchant_1737627877","customer_id":"cus_mBx8CYwaUldk2HbX9qBV","payment_method_id":"pm_nhtWX126LHU1BmoN48TB","payment_method":"card","payment_method_type":null,"card":{"scheme":null,"issuer_country":null,"last4_digits":"0000","expiry_month":"1","expiry_year":"2026","card_token":null,"card_holder_name":null,"card_fingerprint":null,"nick_name":"real joe","card_network":null,"card_isin":"420000","card_issuer":null,"card_type":null,"saved_to_locker":false},"recurring_enabled":true,"installment_payment_enabled":false,"payment_experience":null,"metadata":null,"created":"2025-01-23T10:24:53.998Z","last_used_at":null,"client_secret":null},"customer":{"id":"cus_mBx8CYwaUldk2HbX9qBV","name":"Max Mustermann","email":"[email protected]","phone":null,"phone_country_code":null},"card_tokenized":true,"req":null},{"payment_method_response":{"merchant_id":"merchant_1737627877","customer_id":"cus_tpr9V8N4mPijFOZGbqjH","payment_method_id":"pm_eoyzCgzbJjbfREVKe7c0","payment_method":"card","payment_method_type":null,"card":{"scheme":null,"issuer_country":null,"last4_digits":"0000","expiry_month":"1","expiry_year":"2026","card_token":null,"card_holder_name":null,"card_fingerprint":null,"nick_name":"real joe","card_network":null,"card_isin":"420000","card_issuer":null,"card_type":null,"saved_to_locker":false},"recurring_enabled":true,"installment_payment_enabled":false,"payment_experience":null,"metadata":null,"created":"2025-01-23T10:24:54.001Z","last_used_at":null,"client_secret":null},"customer":{"id":"cus_tpr9V8N4mPijFOZGbqjH","name":"Max Mustermann","email":"[email protected]","phone":null,"phone_country_code":null},"card_tokenized":true,"req":null},{"payment_method_response":{"merchant_id":"merchant_1737627877","customer_id":"cus_fdbpnmVFS3hhYZZfYquM","payment_method_id":"pm_ShvWRpaZyX5kucjVImmw","payment_method":"card","payment_method_type":null,"card":{"scheme":null,"issuer_country":null,"last4_digits":"0000","expiry_month":"1","expiry_year":"2026","card_token":null,"card_holder_name":null,"card_fingerprint":null,"nick_name":"real joe","card_network":null,"card_isin":"420000","card_issuer":null,"card_type":null,"saved_to_locker":false},"recurring_enabled":true,"installment_payment_enabled":false,"payment_experience":null,"metadata":null,"created":"2025-01-23T10:24:54.001Z","last_used_at":null,"client_secret":null},"customer":{"id":"cus_fdbpnmVFS3hhYZZfYquM","name":"Max Mustermann","email":"[email protected]","phone":null,"phone_country_code":null},"card_tokenized":true,"req":null},{"payment_method_response":{"merchant_id":"merchant_1737627877","customer_id":"cus_HeGLoqXGsKYbpCTvvNCX","payment_method_id":"pm_w6QqSyug2w4rJAIxQY4a","payment_method":"card","payment_method_type":null,"card":{"scheme":null,"issuer_country":null,"last4_digits":"0000","expiry_month":"1","expiry_year":"2026","card_token":null,"card_holder_name":null,"card_fingerprint":null,"nick_name":"real joe","card_network":null,"card_isin":"420000","card_issuer":null,"card_type":null,"saved_to_locker":false},"recurring_enabled":true,"installment_payment_enabled":false,"payment_experience":null,"metadata":null,"created":"2025-01-23T10:24:54.009Z","last_used_at":null,"client_secret":null},"customer":{"id":"cus_HeGLoqXGsKYbpCTvvNCX","name":"Max Mustermann","email":"[email protected]","phone":null,"phone_country_code":null},"card_tokenized":true,"req":null},{"payment_method_response":{"merchant_id":"merchant_1737627877","customer_id":"cus_3LgTOBzFOcMHEz1glZzF","payment_method_id":"pm_1G3NGbJG0LyJKvbIZvdJ","payment_method":"card","payment_method_type":null,"card":{"scheme":null,"issuer_country":null,"last4_digits":"0000","expiry_month":"1","expiry_year":"2026","card_token":null,"card_holder_name":null,"card_fingerprint":null,"nick_name":"real joe","card_network":null,"card_isin":"420000","card_issuer":null,"card_type":null,"saved_to_locker":false},"recurring_enabled":true,"installment_payment_enabled":false,"payment_experience":null,"metadata":null,"created":"2025-01-23T10:24:54.009Z","last_used_at":null,"client_secret":null},"customer":{"id":"cus_3LgTOBzFOcMHEz1glZzF","name":"Max Mustermann","email":"[email protected]","phone":null,"phone_country_code":null},"card_tokenized":true,"req":null},{"payment_method_response":{"merchant_id":"merchant_1737627877","customer_id":"cus_bYIVR0NQF4T4bv5KjVNd","payment_method_id":"pm_31KM9k8uPbwUAUaq03N5","payment_method":"card","payment_method_type":null,"card":{"scheme":null,"issuer_country":null,"last4_digits":"0000","expiry_month":"1","expiry_year":"2026","card_token":null,"card_holder_name":null,"card_fingerprint":null,"nick_name":"real joe","card_network":null,"card_isin":"420000","card_issuer":null,"card_type":null,"saved_to_locker":false},"recurring_enabled":true,"installment_payment_enabled":false,"payment_experience":null,"metadata":null,"created":"2025-01-23T10:24:54.010Z","last_used_at":null,"client_secret":null},"customer":{"id":"cus_bYIVR0NQF4T4bv5KjVNd","name":"Max Mustermann","email":"[email protected]","phone":null,"phone_country_code":null},"card_tokenized":true,"req":null},{"payment_method_response":{"merchant_id":"merchant_1737627877","customer_id":"cus_jxMzHRc3Ndfr9Mt2pHKg","payment_method_id":"pm_dAHGSnuIHQC4rHWEGAwF","payment_method":"card","payment_method_type":null,"card":{"scheme":null,"issuer_country":null,"last4_digits":"0000","expiry_month":"1","expiry_year":"25","card_token":null,"card_holder_name":null,"card_fingerprint":null,"nick_name":"real joe","card_network":null,"card_isin":"420000","card_issuer":null,"card_type":null,"saved_to_locker":false},"recurring_enabled":true,"installment_payment_enabled":false,"payment_experience":null,"metadata":null,"created":"2025-01-23T10:24:54.010Z","last_used_at":null,"client_secret":null},"customer":{"id":"cus_jxMzHRc3Ndfr9Mt2pHKg","name":"Max Mustermann","email":"[email protected]","phone":null,"phone_country_code":null},"card_tokenized":true,"req":null},{"payment_method_response":{"merchant_id":"merchant_1737627877","customer_id":"cus_KyauqQZeqKbZCEdRCrPY","payment_method_id":"pm_im8kjgFyc5ydhrHES9z5","payment_method":"card","payment_method_type":null,"card":{"scheme":null,"issuer_country":null,"last4_digits":"0000","expiry_month":"1","expiry_year":"22","card_token":null,"card_holder_name":null,"card_fingerprint":null,"nick_name":"real joe","card_network":null,"card_isin":"420000","card_issuer":null,"card_type":null,"saved_to_locker":false},"recurring_enabled":true,"installment_payment_enabled":false,"payment_experience":null,"metadata":null,"created":"2025-01-23T10:24:54.010Z","last_used_at":null,"client_secret":null},"customer":{"id":"cus_KyauqQZeqKbZCEdRCrPY","name":"Max Mustermann","email":"[email protected]","phone":null,"phone_country_code":null},"card_tokenized":true,"req":null},{"payment_method_response":{"merchant_id":"merchant_1737627877","customer_id":"cus_NuZ4Ntb7hWDXxFt7ro3D","payment_method_id":"pm_gfgZ1gOZ4kIdeBU7Cyqz","payment_method":"card","payment_method_type":null,"card":{"scheme":null,"issuer_country":null,"last4_digits":"0000","expiry_month":"1","expiry_year":"25","card_token":null,"card_holder_name":null,"card_fingerprint":null,"nick_name":"real joe","card_network":null,"card_isin":"420000","card_issuer":null,"card_type":null,"saved_to_locker":false},"recurring_enabled":true,"installment_payment_enabled":false,"payment_experience":null,"metadata":null,"created":"2025-01-23T10:24:54.017Z","last_used_at":null,"client_secret":null},"customer":{"id":"cus_NuZ4Ntb7hWDXxFt7ro3D","name":"Max Mustermann","email":"[email protected]","phone":null,"phone_country_code":null},"card_tokenized":true,"req":null},{"payment_method_response":{"merchant_id":"merchant_1737627877","customer_id":"cus_UDoT3SdLhK62XG7xFo65","payment_method_id":"pm_cPsrZ1S3xV12NnF5uAH8","payment_method":"card","payment_method_type":null,"card":{"scheme":null,"issuer_country":null,"last4_digits":"0000","expiry_month":"1","expiry_year":"25","card_token":null,"card_holder_name":null,"card_fingerprint":null,"nick_name":"real joe","card_network":null,"card_isin":"420000","card_issuer":null,"card_type":null,"saved_to_locker":false},"recurring_enabled":true,"installment_payment_enabled":false,"payment_experience":null,"metadata":null,"created":"2025-01-23T10:24:54.017Z","last_used_at":null,"client_secret":null},"customer":{"id":"cus_UDoT3SdLhK62XG7xFo65","name":"Max Mustermann","email":"[email protected]","phone":null,"phone_country_code":null},"card_tokenized":true,"req":null},{"payment_method_response":{"merchant_id":"merchant_1737627877","customer_id":"cus_cxhCY1RgcvRPlIX891kU","payment_method_id":"pm_iHXORES9dupsE5ffAG0C","payment_method":"card","payment_method_type":null,"card":{"scheme":null,"issuer_country":null,"last4_digits":"0000","expiry_month":"1","expiry_year":"2022","card_token":null,"card_holder_name":null,"card_fingerprint":null,"nick_name":"real joe","card_network":null,"card_isin":"420000","card_issuer":null,"card_type":null,"saved_to_locker":false},"recurring_enabled":true,"installment_payment_enabled":false,"payment_experience":null,"metadata":null,"created":"2025-01-23T10:24:54.017Z","last_used_at":null,"client_secret":null},"customer":{"id":"cus_cxhCY1RgcvRPlIX891kU","name":"Max Mustermann","email":"[email protected]","phone":null,"phone_country_code":null},"card_tokenized":true,"req":null}]

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

@kashif-m kashif-m linked an issue Jan 20, 2025 that may be closed by this pull request
2 tasks
Copy link

semanticdiff-com bot commented Jan 20, 2025

@kashif-m kashif-m marked this pull request as ready for review January 22, 2025 11:57
@kashif-m kashif-m requested review from a team as code owners January 22, 2025 11:57
@kashif-m kashif-m self-assigned this Jan 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FEATURE] expose tokenize endpoints
1 participant