Skip to content

Conversation

apoorvdixit88
Copy link
Contributor

@apoorvdixit88 apoorvdixit88 commented Apr 23, 2025

Type of Change

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

Description

The PR supports onboarding for new VSAAS merchants.

  • Creating Platform Org
  • Creation of Platform, and connected merchant accounts
  • Change List response of merchant and organization list.

Additional Changes

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

Motivation and Context

Closes #7889

How did you test it?

Following Flow:

  • Signup --> terminate 2FA --> List orgs/merchants --> create Merchant inside standard org --> List merchants/orgs to validate
  • CreatePlatform --> Swtich to Platform Org --> List merchants/orgs to validate --> Create Merchant inside platform org

We can hit the following curls:
Signup

curl --location 'http://localhost:8080/user/signup?token_only=true' \
--header 'x-tenant-id: test' \
--header 'Content-Type: application/json' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwicHVycG9zZSI6InRvdHAiLCJvcmlnaW4iOiJzaWduX3VwIiwicGF0aCI6W10sImV4cCI6MTc0NTY1ODA0MywidGVuYW50X2lkIjoicHVibGljIn0.1lHD7fOM64ZtP0rRaBnp5-oaC6vy411jMu-lsjHAyr0' \
--data-raw '{
    "email": "[email protected]",
    "password": "Test@1234"
}'

Response:

{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwicHVycG9zZSI6InRvdHAiLCJvcmlnaW4iOiJzaWduX3VwIiwicGF0aCI6W10sImV4cCI6MTc0NTY1ODA0MywidGVuYW50X2lkIjoicHVibGljIn0.1lHD7fOM64ZtP0rRaBnp5-oaC6vy411jMu-lsjHAyr0","token_type":"totp"}

Terminate 2FA

curl --location 'http://localhost:8080/user/2fa/terminate?skip_two_factor_auth=true' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwicHVycG9zZSI6InRvdHAiLCJvcmlnaW4iOiJzaWduX3VwIiwicGF0aCI6W10sImV4cCI6MTc0NTY1ODA0MywidGVuYW50X2lkIjoicHVibGljIn0.1lHD7fOM64ZtP0rRaBnp5-oaC6vy411jMu-lsjHAyr0' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o'

Response

{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o","token_type":"user_info"}

Create Merchant Account

curl --location 'http://localhost:8080/user/create_merchant' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o' \
--data '{
    "company_name": "in_standard"
}'

Response:

{"merchant_id":"merchant_1745485331","merchant_name":"in_standard","product_type":"orchestration","merchant_account_type":"standard","version":"v1"}

List Orgs

curl --location 'http://localhost:8080/user/list/org' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiZDM2NzMyMTUtYWU3NS00NGMzLWJiYzEtMGY3YmMxYmYwMjdmIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzEyMjE0NDE5Iiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTcxMjM4NzMyOSwib3JnX2lkIjoib3JnXzhLb2lWNmhrcG9KSGZNcllER1ZhIn0.H2G9oGp_JBoz3k5S7fMvaaJ9T0cG5VtUjM0hU3ltM3g' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o'

Response:

[{"org_id":"org_1TaQlxQhcvKA6JVFqHeh","org_name":null,"org_type":"standard"}]

List Merchant

curl --location 'http://localhost:8080/user/list/merchant' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiZDM2NzMyMTUtYWU3NS00NGMzLWJiYzEtMGY3YmMxYmYwMjdmIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzEyMjE0NDE5Iiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTcxMjM4NzMyOSwib3JnX2lkIjoib3JnXzhLb2lWNmhrcG9KSGZNcllER1ZhIn0.H2G9oGp_JBoz3k5S7fMvaaJ9T0cG5VtUjM0hU3ltM3g' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o'

Response:

[{"merchant_id":"merchant_1745485242","merchant_name":null,"product_type":"orchestration","merchant_account_type":"standard","version":"v1"},{"merchant_id":"merchant_1745485331","merchant_name":"in_standard","product_type":"orchestration","merchant_account_type":"standard","version":"v1"}]

Create Platform Org

curl --location 'http://localhost:8080/user/create_platform' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o' \
--data '{
    "organization_name": "platform"
}'

Response: status 200 OK, witth reponse containing platform details

{"org_id":"org_TgxsZW9EOXksNcMSeaUy","org_name":"platform","org_type":"platform","merchant_id":"merchant_1745575171","merchant_account_type":"platform"}

Switch Org

curl --location 'http://localhost:8080/user/switch/org' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1NDg3Iiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODM5OSwib3JnX2lkIjoib3JnXzBFZXE4cU9ETVJGc3NiNGJXa0p5IiwicHJvZmlsZV9pZCI6InByb19QOGc0R0dhbk81dDFiUXczNVQ3aiIsInRlbmFudF9pZCI6InB1YmxpYyJ9.UW9aqcLLXYi_3xOpLCB2vB2ecmMA7M4LHNXorPT0Odc' \
--data '{
    "org_id": "org_0Eeq8qODMRFssb4bWkJy"
}'

Resonse:

{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1NDg3Iiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODM5OSwib3JnX2lkIjoib3JnXzBFZXE4cU9ETVJGc3NiNGJXa0p5IiwicHJvZmlsZV9pZCI6InByb19QOGc0R0dhbk81dDFiUXczNVQ3aiIsInRlbmFudF9pZCI6InB1YmxpYyJ9.UW9aqcLLXYi_3xOpLCB2vB2ecmMA7M4LHNXorPT0Odc","token_type":"user_info"}

Create Merchant inside Platfrom

curl --location 'http://localhost:8080/user/create_merchant' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1NDg3Iiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODM5OSwib3JnX2lkIjoib3JnXzBFZXE4cU9ETVJGc3NiNGJXa0p5IiwicHJvZmlsZV9pZCI6InByb19QOGc0R0dhbk81dDFiUXczNVQ3aiIsInRlbmFudF9pZCI6InB1YmxpYyJ9.UW9aqcLLXYi_3xOpLCB2vB2ecmMA7M4LHNXorPT0Odc' \
--data '{
    "company_name": "in_platform"
}'

Response:

{"merchant_id":"merchant_1745485645","merchant_name":"in_platform","product_type":"orchestration","merchant_account_type":"connected","version":"v1"}

List Org
Now the list orgs for user will give following response since there are two orgs

[{"org_id":"org_0Eeq8qODMRFssb4bWkJy","org_name":"platform","org_type":"platform"},{"org_id":"org_1TaQlxQhcvKA6JVFqHeh","org_name":null,"org_type":"standard"}]

List Merchant
Inside platform there will be following merchants

[{"merchant_id":"merchant_1745485487","merchant_name":null,"product_type":"orchestration","merchant_account_type":"platform","version":"v1"},{"merchant_id":"merchant_1745485645","merchant_name":"in_platform","product_type":"orchestration","merchant_account_type":"connected","version":"v1"}]

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

@apoorvdixit88 apoorvdixit88 self-assigned this Apr 23, 2025
@apoorvdixit88 apoorvdixit88 requested review from a team as code owners April 23, 2025 22:40
Copy link

semanticdiff-com bot commented Apr 23, 2025

@hyperswitch-bot hyperswitch-bot bot added the M-database-changes Metadata: This PR involves database schema changes label Apr 23, 2025
@apoorvdixit88 apoorvdixit88 added A-users Area: Users and removed M-database-changes Metadata: This PR involves database schema changes labels Apr 23, 2025
@hyperswitch-bot hyperswitch-bot bot added the M-database-changes Metadata: This PR involves database schema changes label Apr 23, 2025
maverox
maverox previously approved these changes Apr 24, 2025
maverox
maverox previously approved these changes Apr 25, 2025
ThisIsMani
ThisIsMani previously approved these changes Apr 25, 2025
Copy link
Contributor

@ThisIsMani ThisIsMani left a comment

Choose a reason for hiding this comment

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

Minor concerns.

@apoorvdixit88 apoorvdixit88 dismissed stale reviews from ThisIsMani and maverox via 35c2111 April 28, 2025 08:50
JeevaRamu0104
JeevaRamu0104 previously approved these changes Apr 28, 2025
tsdk02
tsdk02 previously approved these changes Apr 28, 2025
@@ -0,0 +1,5 @@
-- Your SQL goes here
ALTER TABLE organization ADD COLUMN IF NOT EXISTS organization_type VARCHAR(64) NOT NULL DEFAULT 'standard';
Copy link
Member

Choose a reason for hiding this comment

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

we should not add NOT NULL based alter query, and make default in database instead use default value in code and have nullable value in database

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In code it is having default value, but in DB I made it default because that will help to backfill all previous standard cases.
If we don't make it default then we need to run separate migration to backfill old data, is this fine?

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 handle the null cases in code itself

ALTER TABLE organization ADD COLUMN IF NOT EXISTS organization_type VARCHAR(64) NOT NULL DEFAULT 'standard';
ALTER TABLE organization ADD COLUMN IF NOT EXISTS platform_merchant_id VARCHAR(64);

ALTER TABLE merchant_account ADD COLUMN IF NOT EXISTS merchant_account_type VARCHAR(64) NOT NULL DEFAULT 'standard';
Copy link
Member

Choose a reason for hiding this comment

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

we should not add NOT NULL based alter query, and make default in database instead use default value in code and have nullable value in database

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 handle the null cases in code itself

@apoorvdixit88 apoorvdixit88 dismissed stale reviews from tsdk02 and JeevaRamu0104 via 6e1aa71 May 6, 2025 12:35
@Gnanasundari24 Gnanasundari24 added this pull request to the merge queue May 12, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 12, 2025
@Gnanasundari24 Gnanasundari24 added this pull request to the merge queue May 12, 2025
Merged via the queue into main with commit cf34be1 May 12, 2025
15 of 20 checks passed
@Gnanasundari24 Gnanasundari24 deleted the onboarding-for-vsaas branch May 12, 2025 15:02
pixincreate added a commit that referenced this pull request May 12, 2025
…adyen-ideal

* 'main' of github.com:juspay/hyperswitch: (62 commits)
  fix(core): language consumption from locale in payment and payout links (#7993)
  feat(refunds_v2): Add refunds list flow in v2 apis (#7966)
  refactor(connector): [Noon] auth header (#7977)
  fix(connector): [Novalnet] send decoded token for apple pay payment (#7973)
  feat(business_profile): add business_profile config to enable external vault (#7876)
  feat(vsaas): integrate onboarding flow for vertical saas (#7884)
  feat(connector): Introduce connector template code for WorldpayXML  (#7968)
  feat(connector): [ADYEN, CHECKOUT] Added In Feature Matrix API (#7914)
  feat(core): add psync support for recovery external payments (#7855)
  refactor(open_router): call elimination routing of open router if enabled instead of dynamo (#7961)
  feat(payment_methods): add v2 api for fetching token data (#7629)
  ci(cypress): Fix Bank Redirects for stripe test (#8004)
  chore(version): 2025.05.12.0
  refactor(authentication): moved cavv storing from table to temp locker (#7978)
  chore(version): 2025.05.09.0
  feat(connector): [paypal, trustpay] add in feature matrix (#7911)
  fix(update_metadata): Update Metadata for any connectors other than stripe gives 500 error (#7984)
  fix(router): Fixed stack over flow for session call in authentication connectors (#7983)
  chore(version): 2025.05.08.0
  fix(payment): disable payment update via client config (#7970)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-users Area: Users M-database-changes Metadata: This PR involves database schema changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add onboarding flow for VSAAS
8 participants