feat(tokenio): Add OpenBanking Redirection Flow#8152
Conversation
1e18b97 to
7045f58
Compare
1747552 to
9d67363
Compare
| #[serde(skip_serializing_if = "Option::is_none")] | ||
| connector_recipient_id: Option<Secret<String>>, | ||
| }, | ||
| Sepa { |
There was a problem hiding this comment.
I think we dont need SEPA here as we already have IBAN?
There was a problem hiding this comment.
it was there in the docs
https://reference.token.io/tag/Payments-v2#operation/InitiatePayment
There was a problem hiding this comment.
Can't we have a transform for this as all the fields are the same here.
|
|
||
| #[cfg(all(feature = "v2", feature = "revenue_recovery"))] | ||
| default_imp_for_billing_connector_invoice_sync!( | ||
| connectors::Tokenio, |
There was a problem hiding this comment.
alphabetical order
| } | ||
|
|
||
| // JWT helper methods | ||
| // fn create_jwt_token( |
There was a problem hiding this comment.
we can remove this comment.
9d67363 to
40122b1
Compare
f617f7f to
9ad4a1b
Compare
| #[serde(skip_serializing_if = "Option::is_none")] | ||
| connector_recipient_id: Option<Secret<String>>, | ||
| }, | ||
| FasterPayments { |
There was a problem hiding this comment.
Add documentation for all the fields
| if serde_json::from_str::<serde_json::Value>(&enc_card_data).is_ok() { | ||
| logger::debug!("Data appears to be plain JSON, returning as-is"); | ||
| return Ok(Secret::new(enc_card_data)); | ||
| } |
There was a problem hiding this comment.
The function says decode and decrypt data so here we are not supposed to get the plan data.
If there is a case where some data does not need to be encrypted, what kind of data would that be?
If we are storing it in a locker, isn't all of it considered sensitive?
There was a problem hiding this comment.
Earlier, we were not storing the bank details in the locker — for example, in the case of Plaid, this was not being done.
I’ve now added the encryption logic in the async fn locker_recipient_create_call function
Also removed this check as its not needed any more
| @@ -152,21 +152,32 @@ pub enum PlaidRecipientAccountData { | |||
| }, | |||
| } | |||
There was a problem hiding this comment.
@Sarthak1799 can you review the plaid related changes ?
crates/common_utils/src/crypto.rs
Outdated
| let public_key = ring::signature::UnparsedPublicKey::new(&ring::signature::ED25519, secret); | ||
| match public_key.verify(msg, signature) { | ||
| Ok(()) => Ok(true), | ||
| Err(_) => Ok(false), |
There was a problem hiding this comment.
Returning Ok(false) when a signature fails might hide problems—most cryptographic signature verification functions return an error on failure. Returning Ok(false) makes it harder to distinguish between actual errors and valid rejections.
There was a problem hiding this comment.
raising error now
Err(_) => {
// Signature verification failed - this is a legitimate failure,
// not an error condition. The signature is well-formed but invalid.
Err(errors::CryptoError::SignatureVerificationFailed)
.attach_printable("ED25519 signature verification failed")
}
crates/common_utils/src/crypto.rs
Outdated
| if secret.len() != 32 { | ||
| return Err(errors::CryptoError::InvalidKeyLength).attach_printable(format!( | ||
| "Invalid ED25519 public key length: expected 32 bytes, got {}", | ||
| secret.len() | ||
| )); | ||
| } | ||
| if signature.len() != 64 { | ||
| return Err(errors::CryptoError::SignatureVerificationFailed).attach_printable( | ||
| format!( | ||
| "Invalid ED25519 signature length: expected 64 bytes, got {}", | ||
| signature.len() | ||
| ), | ||
| ); | ||
| } |
There was a problem hiding this comment.
If this validation is generic to Ed25519 the have these as constants. Create a function for validation that will have the above logic.
const ED25519_PUBLIC_KEY_LEN: usize = 32;
const ED25519_SIGNATURE_LEN: usize = 64;
There was a problem hiding this comment.
yes this generic to Ed25519
added a new function to validate the inputs
impl Ed25519 {
/// ED25519 algorithm constants
const ED25519_PUBLIC_KEY_LEN: usize = 32;
const ED25519_SIGNATURE_LEN: usize = 64;
/// Validates ED25519 inputs (public key and signature lengths)
fn validate_inputs(
public_key: &[u8],
signature: &[u8],
) -> CustomResult<(), errors::CryptoError> {
// Validate public key length
if public_key.len() != Self::ED25519_PUBLIC_KEY_LEN {
return Err(errors::CryptoError::InvalidKeyLength).attach_printable(format!(
"Invalid ED25519 public key length: expected {} bytes, got {}",
Self::ED25519_PUBLIC_KEY_LEN,
public_key.len()
));
}
// Validate signature length
if signature.len() != Self::ED25519_SIGNATURE_LEN {
return Err(errors::CryptoError::InvalidKeyLength).attach_printable(format!(
"Invalid ED25519 signature length: expected {} bytes, got {}",
Self::ED25519_SIGNATURE_LEN,
signature.len()
));
}
Ok(())
}
}
7fc2ada to
56e31af
Compare
f7d3a29 to
84cd2e9
Compare
Sarthak1799
left a comment
There was a problem hiding this comment.
Plaid specific changes look okay.
313907b
4ec961d to
313907b
Compare
313907b to
5e02fa6
Compare
| // Perform verification | ||
| match ring_public_key.verify(msg, signature) { | ||
| Ok(()) => Ok(true), | ||
| Err(_err) => { |
There was a problem hiding this comment.
Nit:
| Err(_err) => { | |
| Err(err) => { |
…nktransfer * 'main' of github.com:juspay/hyperswitch: (211 commits) feat(tokenio): Add OpenBanking Redirection Flow (#8152) fix: Unified scarf setup (#8238) feat(health): Health check for Decision engine (#8243) chore: Update apple pay currency filter configs (#8217) refactor(customers_v2): Remove merchant reference id from v2 customer update (#7879) chore(version): 2025.06.09.0 chore(postman): update Postman collection files ci(postman): add tunnel collection to postman tests (#8269) feat(connector): Added recurring payments support for split payments in Stripe (#8271) feat(connector): [STRIPE] Added Connector Tokenization Flow for Cards (#8248) refactor(core): introduce new field in payment_intent to handle longer return_url (#8135) fix(connector): [AUTHORIZEDOTNET] Remove country PM filters (#8278) refactor(config): redact config urls for hyperswitch vault (#8276) feat(vsaas): enable onboarding of Standard Merchant Accounts in Platform Organization (#8231) feat(router): add three_ds decision rule execute api (#8148) feat(router): Save payment method on payments confirm (V2) (#8090) ci(cypress): Add Airwallex Connector Test (#8187) feat(payment_methods): add `external_vault_details` for payments v2 sdk session call (#8003) fix(connector): [facilitapay] cpf is a required field (#8274) fix: Fixed spell check (#8227) ...
…ordea-sepa * 'main' of github.com:juspay/hyperswitch: (63 commits) feat(connector): [TRUSTPAY] Added Integrity Checks for PSync & RSync flows & Added New Variants in AttemptStatus & IntentStatus (#8096) fix(connector): [STRIPE] Throwing Missing Required Field Error if connector_customer is not present (#8309) refactor(connectors): [worldpayvantiv] replace sandbox url with pre-live url and fix typo (#8286) fix: payment link styling for dynamic classes (#8273) feat(core): Make installment_payment_enabled,recurring_enabled Optional (#8201) fix(cypress): fix itaubank, datatrans and facilitapay (#8229) fix(connector): [jpmorgan] 5xx during payment authorize and `cancellation_reason` (#8282) revert(connector): [Worldpay] add root CA certificate (#8224) ci(cypress): fix fiuu, fiservemea , paybox and worldpay connector (#8209) fix(connector): removed forked josekit dependency from payout connector Nomupay (#8183) chore(version): 2025.06.10.0 feat(tokenio): Add OpenBanking Redirection Flow (#8152) fix: Unified scarf setup (#8238) feat(health): Health check for Decision engine (#8243) chore: Update apple pay currency filter configs (#8217) refactor(customers_v2): Remove merchant reference id from v2 customer update (#7879) chore(version): 2025.06.09.0 chore(postman): update Postman collection files ci(postman): add tunnel collection to postman tests (#8269) feat(connector): Added recurring payments support for split payments in Stripe (#8271) ...
…ordea-sepa * 'main' of github.com:juspay/hyperswitch: (63 commits) feat(connector): [TRUSTPAY] Added Integrity Checks for PSync & RSync flows & Added New Variants in AttemptStatus & IntentStatus (#8096) fix(connector): [STRIPE] Throwing Missing Required Field Error if connector_customer is not present (#8309) refactor(connectors): [worldpayvantiv] replace sandbox url with pre-live url and fix typo (#8286) fix: payment link styling for dynamic classes (#8273) feat(core): Make installment_payment_enabled,recurring_enabled Optional (#8201) fix(cypress): fix itaubank, datatrans and facilitapay (#8229) fix(connector): [jpmorgan] 5xx during payment authorize and `cancellation_reason` (#8282) revert(connector): [Worldpay] add root CA certificate (#8224) ci(cypress): fix fiuu, fiservemea , paybox and worldpay connector (#8209) fix(connector): removed forked josekit dependency from payout connector Nomupay (#8183) chore(version): 2025.06.10.0 feat(tokenio): Add OpenBanking Redirection Flow (#8152) fix: Unified scarf setup (#8238) feat(health): Health check for Decision engine (#8243) chore: Update apple pay currency filter configs (#8217) refactor(customers_v2): Remove merchant reference id from v2 customer update (#7879) chore(version): 2025.06.09.0 chore(postman): update Postman collection files ci(postman): add tunnel collection to postman tests (#8269) feat(connector): Added recurring payments support for split payments in Stripe (#8271) ...
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Type of Change
Description
Added OpenBanking Flow for Tokenio
Additional Changes
Motivation and Context
How did you test it?
MCA Create
Payments Create
Response
Checklist
cargo +nightly fmt --allcargo clippy