juspay/hyperswitch · error
Globalpay requires BodyKey auth type
Error message
Globalpay requires BodyKey auth type
What it means
Globalpay authenticates with app credentials sent in the request body (app_id + app_key), so the unified connector config accepts only `ConnectorAuthType::BodyKey` (with `key1` as app_id and `api_key` as app_key). Any other auth type falls into the catch-all arm and returns this error instead of building `Self::Globalpay`.
Solutions
- Re-save the Globalpay connector credential as `ConnectorAuthType::BodyKey` with app_key in `api_key` and app_id in `key1`
- Optionally include conforming Globalpay metadata (account_name) in the same call
- Migrate any wrongly-shaped stored credentials for Globalpay merchants
- Retry a test transaction after updating the connector config
Example fix
// before
ConnectorAuthType::SignatureKey { api_key, key1, api_secret }
// after
ConnectorAuthType::BodyKey { api_key: app_key, key1: app_id } Defensive patterns
Strategy: validation
Validate before calling
fn is_globalpay_auth(auth: &ConnectorAuthType) -> bool {
matches!(auth, ConnectorAuthType::BodyKey { .. })
}
if !is_globalpay_auth(&auth) {
return Err(report!(ConfigError::InvalidConnectorAuth("Globalpay 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::Globalpay, &auth, metadata) {
Ok(cfg) => use_config(cfg),
Err(e) if e.current_context().to_string().contains("BodyKey") => {
// re-collect Globalpay app_id/app_key as BodyKey
}
Err(e) => return Err(e),
} Prevention
- Enforce the BodyKey layout in the Globalpay connector onboarding form
- Require both app_id (key1) and app_key (api_key) at entry time
- Add compile-time or config-time checks mapping connector -> expected auth type
When it happens
Trigger: Configuring the Globalpay connector with `SignatureKey`, `HeaderKey`, `CertificateKey`, or `NoKey` auth types, then performing any operation that resolves connector config in `connector_config.rs`.
Common situations: Merchant enters Globalpay credentials under a SignatureKey-style connector template; automated provisioning scripts default to HeaderKey; credentials copied from another connector's config shape.
Related errors
- Datatrans requires BodyKey auth type
- Etisalat requires SignatureKey auth type
- Invalid Globalpay metadata format
- Merchante requires BodyKey auth type
- Failed to create GCP KMS client
AI-assisted analysis of juspay/hyperswitch@afd9284352 (2026-09-18).
Data as JSON: /api/errors/00c3e34508b3a3d5.
Report an issue: GitHub.
Appendix: source
Thrown at crates/router/src/core/unified_connector_service/connector_config.rs:1074
}),
_ => 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")),
},
Connector::Hipay => match auth {
ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self::Hipay {
api_key: api_key.clone(),
api_secret: key1.clone(),
}),
_ => Err(err("Hipay requires BodyKey auth type")),
},
Connector::Jpmorgan => match auth {
ConnectorAuthType::BodyKey { api_key, key1 } => {
let jpm_meta = metadata
.map(|m| {
m.clone()
.parse_value::<JpmorganMetadata>("JpmorganMetadata")
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Invalid Jpmorgan metadata format")
})
.transpose()?;View on GitHub (pinned to afd9284352)