juspay/hyperswitch · error
Datatrans requires BodyKey auth type
Error message
Datatrans requires BodyKey auth type
What it means
Hyperswitch's unified connector configuration converts a merchant's `ConnectorAuthType` into the connector-specific auth struct. Datatrans authenticates with credentials carried in the request body (merchant ID + password), so only `ConnectorAuthType::BodyKey` is accepted. Any other auth type produces this error via the catch-all match arm, converting the merchant connector into `Self::Datatrans` fails.
Solutions
- Re-configure the Datatrans connector credential with `ConnectorAuthType::BodyKey`, mapping password/api_key to `api_key` and merchant_id to `key1`
- Update the connector creation API call so `connector_type`/auth layout matches BodyKey (two fields)
- If data was seeded wrongly, migrate existing merchant_connector_credentials rows for Datatrans to the BodyKey shape
- Verify with a health/check call for the connector after re-saving credentials
Example fix
// before
ConnectorAuthType::HeaderKey { api_key }
// after
ConnectorAuthType::BodyKey {
api_key: datatrans_password,
key1: datatrans_merchant_id,
} Defensive patterns
Strategy: validation
Validate before calling
fn is_datatrans_auth(auth: &ConnectorAuthType) -> bool {
matches!(auth, ConnectorAuthType::BodyKey { .. })
}
if !is_datatrans_auth(&auth) {
return Err(report!(ConfigError::InvalidConnectorAuth("Datatrans requires BodyKey")));
} Type guard
fn as_body_key(auth: &ConnectorAuthType) -> Option<(&String, &String)> {
match auth {
ConnectorAuthType::BodyKey { api_key, key1 } => Some((api_key, key1)),
_ => None,
}
} Try / catch
match build_connector_config(Connector::Datatrans, &auth, metadata) {
Ok(cfg) => use_config(cfg),
Err(e) if e.current_context().to_string().contains("BodyKey") => {
// prompt re-entry of Datatrans credentials as BodyKey
}
Err(e) => return Err(e),
} Prevention
- Use connector-specific auth-shape validators before saving credentials
- Validate both BodyKey fields (api_key, key1) are non-empty at credential entry time
- Keep connector auth templates aligned with the required type in connector_config.rs
When it happens
Trigger: Configuring the Datatrans connector with `ConnectorAuthType::SignatureKey`, `HeaderKey`, `CertificateKey`, `BodyKey` missing `key1`, or `NoKey`, then attempting a payment or connector-credential conversion in `connector_config.rs`.
Common situations: Merchant selects the wrong auth layout in the connector dashboard/API when adding Datatrans credentials; migration or seed data created credentials as HeaderKey; tenant config scripts pass api_key only without the required second key.
Related errors
- Etisalat requires SignatureKey auth type
- Globalpay requires BodyKey auth type
- Merchante requires BodyKey auth type
- Failed to create GCP KMS client
- Invalid Globalpay metadata format
AI-assisted analysis of juspay/hyperswitch@afd9284352 (2026-09-18).
Data as JSON: /api/errors/83bcf2894279b3b6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/router/src/core/unified_connector_service/connector_config.rs:1057
ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self::Bluesnap {
username: key1.clone(),
password: api_key.clone(),
}),
_ => Err(err("Bluesnap requires BodyKey auth type")),
},
Connector::Cryptopay => match auth {
ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self::Cryptopay {
api_key: api_key.clone(),
api_secret: key1.clone(),
}),
_ => Err(err("Cryptopay requires BodyKey auth type")),
},
Connector::Datatrans => match auth {
ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self::Datatrans {
merchant_id: key1.clone(),
password: api_key.clone(),
}),
_ => Err(err("Datatrans requires BodyKey auth type")),
},
Connector::Globalpay => match auth {
ConnectorAuthType::BodyKey { api_key, key1 } => {
let globalpay_meta = metadata
.map(|m| {
serde_json::from_value::<GlobalpayMetadata>(m.clone())
.map_err(|_| err("Invalid Globalpay metadata format"))
})
.transpose()?;
Ok(Self::Globalpay {
app_id: key1.clone(),
app_key: api_key.clone(),
account_name: globalpay_meta.and_then(|m| m.account_name),
})
}
_ => Err(err("Globalpay requires BodyKey auth type")),
},View on GitHub (pinned to afd9284352)