juspay/hyperswitch · error
Merchante requires BodyKey auth type
Error message
Merchante requires BodyKey auth type
What it means
Merchante authenticates with a profile key and profile ID carried in the request body, so only `ConnectorAuthType::BodyKey` is accepted (api_key -> 32-char profile key, key1 -> 20-digit profile ID). Any other auth type falls through to the catch-all arm and returns this error instead of building `Self::Merchante`.
Solutions
- Re-save the Merchante credential as `ConnectorAuthType::BodyKey` with the 32-char profile key in `api_key` and the 20-digit profile ID in `key1`
- Check the values are in the right fields (profile_key/profile_id mapping shown in the source comments)
- Migrate any wrongly-shaped stored credentials for Merchante merchants
- Retry a test payment after updating the connector config
Example fix
// before
ConnectorAuthType::HeaderKey { api_key: profile_key }
// after
ConnectorAuthType::BodyKey {
api_key: merchante_profile_key,
key1: merchante_profile_id,
} Defensive patterns
Strategy: validation
Validate before calling
fn is_merchante_auth(auth: &ConnectorAuthType) -> bool {
matches!(auth, ConnectorAuthType::BodyKey { .. })
}
if !is_merchante_auth(&auth) {
return Err(report!(ConfigError::InvalidConnectorAuth("Merchante 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::Merchante, &auth, metadata) {
Ok(cfg) => use_config(cfg),
Err(e) if e.current_context().to_string().contains("BodyKey") => {
// re-collect Merchante profile_key/profile_id as BodyKey
}
Err(e) => return Err(e),
} Prevention
- Check api_key is the 32-char profile key and key1 is the 20-digit profile ID before saving
- Use the Merchante-specific onboarding template rather than copying SignatureKey connectors
- Validate field lengths/types at credential entry time
When it happens
Trigger: Configuring the Merchante connector with `SignatureKey`, `HeaderKey`, `CertificateKey`, or `NoKey` auth types, then executing any operation that resolves the Merchante connector config in `connector_config.rs`.
Common situations: Merchant mistakenly chooses a SignatureKey-based template (e.g. copying an Etisalat/Noon config); automation stores credentials as HeaderKey; profile ID entered into the api_key slot so the shape no longer matches.
Related errors
- Datatrans requires BodyKey auth type
- Etisalat requires SignatureKey auth type
- Globalpay 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/6b09ecd8e1eb8895.
Report an issue: GitHub.
Appendix: source
Thrown at crates/router/src/core/unified_connector_service/connector_config.rs:1454
api_key,
key1,
api_secret,
} => Ok(Self::Etisalat {
user_name: api_key.clone(),
password: key1.clone(),
customer: api_secret.clone(),
}),
_ => Err(err("Etisalat requires SignatureKey auth type")),
},
Connector::Merchante => match auth {
// api_key -> Merchante Profile Key (32-char secret),
// key1 -> Merchante Profile ID (20-digit merchant id).
// Mirrors the hyperswitch-prism `ConnectorEnum::Merchante` arm.
ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self::Merchante {
profile_key: api_key.clone(),
profile_id: key1.clone(),
}),
_ => Err(err("Merchante requires BodyKey auth type")),
},
Connector::Noon => match auth {
ConnectorAuthType::SignatureKey {
api_key,
key1,
api_secret,
} => Ok(Self::Noon {
api_key: api_key.clone(),
business_identifier: key1.clone(),
application_identifier: api_secret.clone(),
}),
_ => Err(err("Noon requires SignatureKey auth type")),
},
Connector::Novalnet => match auth {
ConnectorAuthType::SignatureKey {
api_key,
key1,
api_secret,View on GitHub (pinned to afd9284352)