mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 17:19:15 +08:00
feat(documentation): add polymorphic generate_schema macro (#1183)
Co-authored-by: pixincreate@work <69745008+pixincreate@users.noreply.github.com>
This commit is contained in:
@ -321,7 +321,9 @@ impl From<StraightThroughAlgorithm> for StraightThroughAlgorithmSerde {
|
|||||||
#[derive(Clone, Debug, Deserialize, ToSchema, Serialize)]
|
#[derive(Clone, Debug, Deserialize, ToSchema, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct PrimaryBusinessDetails {
|
pub struct PrimaryBusinessDetails {
|
||||||
|
#[schema(value_type = CountryAlpha2)]
|
||||||
pub country: api_enums::CountryAlpha2,
|
pub country: api_enums::CountryAlpha2,
|
||||||
|
#[schema(example = "food")]
|
||||||
pub business: String,
|
pub business: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,10 +454,12 @@ pub struct MerchantConnectorCreate {
|
|||||||
pub frm_configs: Option<FrmConfigs>,
|
pub frm_configs: Option<FrmConfigs>,
|
||||||
|
|
||||||
/// Business Country of the connector
|
/// Business Country of the connector
|
||||||
#[schema(value_type = CountryAlpha2, example = "US")]
|
|
||||||
#[cfg(feature = "multiple_mca")]
|
#[cfg(feature = "multiple_mca")]
|
||||||
|
#[schema(value_type = CountryAlpha2, example = "US")]
|
||||||
pub business_country: api_enums::CountryAlpha2,
|
pub business_country: api_enums::CountryAlpha2,
|
||||||
|
|
||||||
#[cfg(not(feature = "multiple_mca"))]
|
#[cfg(not(feature = "multiple_mca"))]
|
||||||
|
#[schema(value_type = Option<CountryAlpha2>, example = "US")]
|
||||||
pub business_country: Option<api_enums::CountryAlpha2>,
|
pub business_country: Option<api_enums::CountryAlpha2>,
|
||||||
|
|
||||||
///Business Type of the merchant
|
///Business Type of the merchant
|
||||||
@ -633,7 +637,11 @@ pub struct FrmConfigs {
|
|||||||
pub frm_enabled_pms: Option<Vec<String>>,
|
pub frm_enabled_pms: Option<Vec<String>>,
|
||||||
pub frm_enabled_pm_types: Option<Vec<String>>,
|
pub frm_enabled_pm_types: Option<Vec<String>>,
|
||||||
pub frm_enabled_gateways: Option<Vec<String>>,
|
pub frm_enabled_gateways: Option<Vec<String>>,
|
||||||
pub frm_action: api_enums::FrmAction, //What should be the action if FRM declines the txn (autorefund/cancel txn/manual review)
|
/// What should be the action if FRM declines the txn (autorefund/cancel txn/manual review)
|
||||||
|
#[schema(value_type = FrmAction)]
|
||||||
|
pub frm_action: api_enums::FrmAction,
|
||||||
|
/// Whether to make a call to the FRM before or after the payment
|
||||||
|
#[schema(value_type = FrmPreferredFlowTypes)]
|
||||||
pub frm_preferred_flow_type: api_enums::FrmPreferredFlowTypes,
|
pub frm_preferred_flow_type: api_enums::FrmPreferredFlowTypes,
|
||||||
}
|
}
|
||||||
/// Details of all the payment methods enabled for the connector for the given merchant account
|
/// Details of all the payment methods enabled for the connector for the given merchant account
|
||||||
@ -657,7 +665,9 @@ pub struct PaymentMethodsEnabled {
|
|||||||
rename_all = "snake_case"
|
rename_all = "snake_case"
|
||||||
)]
|
)]
|
||||||
pub enum AcceptedCurrencies {
|
pub enum AcceptedCurrencies {
|
||||||
|
#[schema(value_type = Vec<Currency>)]
|
||||||
EnableOnly(Vec<api_enums::Currency>),
|
EnableOnly(Vec<api_enums::Currency>),
|
||||||
|
#[schema(value_type = Vec<Currency>)]
|
||||||
DisableOnly(Vec<api_enums::Currency>),
|
DisableOnly(Vec<api_enums::Currency>),
|
||||||
AllAccepted,
|
AllAccepted,
|
||||||
}
|
}
|
||||||
@ -670,7 +680,9 @@ pub enum AcceptedCurrencies {
|
|||||||
rename_all = "snake_case"
|
rename_all = "snake_case"
|
||||||
)]
|
)]
|
||||||
pub enum AcceptedCountries {
|
pub enum AcceptedCountries {
|
||||||
|
#[schema(value_type = Vec<CountryAlpha2>)]
|
||||||
EnableOnly(Vec<api_enums::CountryAlpha2>),
|
EnableOnly(Vec<api_enums::CountryAlpha2>),
|
||||||
|
#[schema(value_type = Vec<CountryAlpha2>)]
|
||||||
DisableOnly(Vec<api_enums::CountryAlpha2>),
|
DisableOnly(Vec<api_enums::CountryAlpha2>),
|
||||||
AllAccepted,
|
AllAccepted,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,16 @@ pub struct BankCodeResponse {
|
|||||||
pub eligible_connectors: Vec<String>,
|
pub eligible_connectors: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
|
#[derive(
|
||||||
|
Default,
|
||||||
|
Debug,
|
||||||
|
serde::Deserialize,
|
||||||
|
serde::Serialize,
|
||||||
|
Clone,
|
||||||
|
ToSchema,
|
||||||
|
router_derive::PolymorphicSchema,
|
||||||
|
)]
|
||||||
|
#[generate_schemas(PaymentsCreateRequest)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct PaymentsRequest {
|
pub struct PaymentsRequest {
|
||||||
/// Unique identifier for the payment. This ensures idempotency for multiple payments
|
/// Unique identifier for the payment. This ensures idempotency for multiple payments
|
||||||
@ -64,6 +73,8 @@ pub struct PaymentsRequest {
|
|||||||
/// The payment amount. Amount for the payment in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc.,
|
/// The payment amount. Amount for the payment in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc.,
|
||||||
#[schema(value_type = Option<u64>, example = 6540)]
|
#[schema(value_type = Option<u64>, example = 6540)]
|
||||||
#[serde(default, deserialize_with = "amount::deserialize_option")]
|
#[serde(default, deserialize_with = "amount::deserialize_option")]
|
||||||
|
#[mandatory_in(PaymentsCreateRequest)]
|
||||||
|
// Makes the field mandatory in PaymentsCreateRequest
|
||||||
pub amount: Option<Amount>,
|
pub amount: Option<Amount>,
|
||||||
|
|
||||||
#[schema(value_type = Option<RoutingAlgorithm>, example = json!({
|
#[schema(value_type = Option<RoutingAlgorithm>, example = json!({
|
||||||
@ -78,6 +89,7 @@ pub struct PaymentsRequest {
|
|||||||
|
|
||||||
/// The currency of the payment request can be specified here
|
/// The currency of the payment request can be specified here
|
||||||
#[schema(value_type = Option<Currency>, example = "USD")]
|
#[schema(value_type = Option<Currency>, example = "USD")]
|
||||||
|
#[mandatory_in(PaymentsCreateRequest)]
|
||||||
pub currency: Option<api_enums::Currency>,
|
pub currency: Option<api_enums::Currency>,
|
||||||
|
|
||||||
/// This is the instruction for capture/ debit the money from the users' card. On the other hand authorization refers to blocking the amount on the users' payment method.
|
/// This is the instruction for capture/ debit the money from the users' card. On the other hand authorization refers to blocking the amount on the users' payment method.
|
||||||
@ -205,7 +217,7 @@ pub struct PaymentsRequest {
|
|||||||
pub payment_method_type: Option<api_enums::PaymentMethodType>,
|
pub payment_method_type: Option<api_enums::PaymentMethodType>,
|
||||||
|
|
||||||
/// Business country of the merchant for this payment
|
/// Business country of the merchant for this payment
|
||||||
#[schema(value_type = CountryAlpha2, example = "US")]
|
#[schema(value_type = Option<CountryAlpha2>, example = "US")]
|
||||||
pub business_country: Option<api_enums::CountryAlpha2>,
|
pub business_country: Option<api_enums::CountryAlpha2>,
|
||||||
|
|
||||||
/// Business label of the merchant for this payment
|
/// Business label of the merchant for this payment
|
||||||
@ -213,6 +225,7 @@ pub struct PaymentsRequest {
|
|||||||
pub business_label: Option<String>,
|
pub business_label: Option<String>,
|
||||||
|
|
||||||
/// Merchant connector details used to make payments.
|
/// Merchant connector details used to make payments.
|
||||||
|
#[schema(value_type = Option<MerchantConnectorDetailsWrap>)]
|
||||||
pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
|
pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
|
||||||
|
|
||||||
/// Allowed Payment Method Types for a given PaymentIntent
|
/// Allowed Payment Method Types for a given PaymentIntent
|
||||||
@ -637,7 +650,13 @@ pub enum BankRedirectData {
|
|||||||
/// The billing details for bank redirection
|
/// The billing details for bank redirection
|
||||||
billing_details: BankRedirectBilling,
|
billing_details: BankRedirectBilling,
|
||||||
/// Bank account details for Giropay
|
/// Bank account details for Giropay
|
||||||
|
|
||||||
|
#[schema(value_type = Option<String>)]
|
||||||
|
/// Bank account bic code
|
||||||
bank_account_bic: Option<Secret<String>>,
|
bank_account_bic: Option<Secret<String>>,
|
||||||
|
|
||||||
|
/// Bank account iban
|
||||||
|
#[schema(value_type = Option<String>)]
|
||||||
bank_account_iban: Option<Secret<String>>,
|
bank_account_iban: Option<Secret<String>>,
|
||||||
},
|
},
|
||||||
Ideal {
|
Ideal {
|
||||||
@ -653,26 +672,32 @@ pub enum BankRedirectData {
|
|||||||
#[schema(value_type = CountryAlpha2, example = "US")]
|
#[schema(value_type = CountryAlpha2, example = "US")]
|
||||||
country: api_enums::CountryAlpha2,
|
country: api_enums::CountryAlpha2,
|
||||||
|
|
||||||
|
#[schema(value_type = String, example = "john.doe@example.com")]
|
||||||
email: Email,
|
email: Email,
|
||||||
},
|
},
|
||||||
OnlineBankingCzechRepublic {
|
OnlineBankingCzechRepublic {
|
||||||
// Issuer banks
|
// Issuer banks
|
||||||
|
#[schema(value_type = BankNames)]
|
||||||
issuer: api_enums::BankNames,
|
issuer: api_enums::BankNames,
|
||||||
},
|
},
|
||||||
OnlineBankingFinland {
|
OnlineBankingFinland {
|
||||||
// Shopper Email
|
// Shopper Email
|
||||||
|
#[schema(value_type = Option<String>)]
|
||||||
email: Option<Email>,
|
email: Option<Email>,
|
||||||
},
|
},
|
||||||
OnlineBankingPoland {
|
OnlineBankingPoland {
|
||||||
// Issuer banks
|
// Issuer banks
|
||||||
|
#[schema(value_type = BankNames)]
|
||||||
issuer: api_enums::BankNames,
|
issuer: api_enums::BankNames,
|
||||||
},
|
},
|
||||||
OnlineBankingSlovakia {
|
OnlineBankingSlovakia {
|
||||||
// Issuer value corresponds to the bank
|
// Issuer value corresponds to the bank
|
||||||
|
#[schema(value_type = BankNames)]
|
||||||
issuer: api_enums::BankNames,
|
issuer: api_enums::BankNames,
|
||||||
},
|
},
|
||||||
Przelewy24 {
|
Przelewy24 {
|
||||||
//Issuer banks
|
//Issuer banks
|
||||||
|
#[schema(value_type = Option<BankNames>)]
|
||||||
bank_name: Option<api_enums::BankNames>,
|
bank_name: Option<api_enums::BankNames>,
|
||||||
|
|
||||||
// The billing details for bank redirect
|
// The billing details for bank redirect
|
||||||
@ -796,6 +821,7 @@ pub struct MobilePayRedirection {}
|
|||||||
#[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
|
#[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
|
||||||
pub struct MbWayRedirection {
|
pub struct MbWayRedirection {
|
||||||
/// Telephone number of the shopper. Should be Portuguese phone number.
|
/// Telephone number of the shopper. Should be Portuguese phone number.
|
||||||
|
#[schema(value_type = String)]
|
||||||
pub telephone_number: Secret<String>,
|
pub telephone_number: Secret<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1008,6 +1034,7 @@ pub struct PaymentsCaptureRequest {
|
|||||||
/// Concatenated with the statement descriptor suffix that’s set on the account to form the complete statement descriptor.
|
/// Concatenated with the statement descriptor suffix that’s set on the account to form the complete statement descriptor.
|
||||||
pub statement_descriptor_prefix: Option<String>,
|
pub statement_descriptor_prefix: Option<String>,
|
||||||
/// Merchant connector details used to make payments.
|
/// Merchant connector details used to make payments.
|
||||||
|
#[schema(value_type = Option<MerchantConnectorDetailsWrap>)]
|
||||||
pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
|
pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1231,6 +1258,7 @@ pub struct PaymentsResponse {
|
|||||||
pub connector_label: Option<String>,
|
pub connector_label: Option<String>,
|
||||||
|
|
||||||
/// The business country of merchant for this payment
|
/// The business country of merchant for this payment
|
||||||
|
#[schema(value_type = CountryAlpha2)]
|
||||||
pub business_country: api_enums::CountryAlpha2,
|
pub business_country: api_enums::CountryAlpha2,
|
||||||
|
|
||||||
/// The business label of merchant for this payment
|
/// The business label of merchant for this payment
|
||||||
@ -1487,6 +1515,7 @@ pub struct PaymentsRetrieveRequest {
|
|||||||
/// The name of the connector
|
/// The name of the connector
|
||||||
pub connector: Option<String>,
|
pub connector: Option<String>,
|
||||||
/// Merchant connector details used to make payments.
|
/// Merchant connector details used to make payments.
|
||||||
|
#[schema(value_type = Option<MerchantConnectorDetailsWrap>)]
|
||||||
pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
|
pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1510,7 +1539,9 @@ pub struct Metadata {
|
|||||||
#[schema(value_type = Object, example = r#"{ "city": "NY", "unit": "245" }"#)]
|
#[schema(value_type = Object, example = r#"{ "city": "NY", "unit": "245" }"#)]
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub data: pii::SecretSerdeValue,
|
pub data: pii::SecretSerdeValue,
|
||||||
|
|
||||||
/// Payload coming in request as a metadata field
|
/// Payload coming in request as a metadata field
|
||||||
|
#[schema(value_type = Option<Object>)]
|
||||||
pub payload: Option<pii::SecretSerdeValue>,
|
pub payload: Option<pii::SecretSerdeValue>,
|
||||||
|
|
||||||
/// Allowed payment method types for a payment intent
|
/// Allowed payment method types for a payment intent
|
||||||
@ -1528,6 +1559,7 @@ pub struct PaymentsSessionRequest {
|
|||||||
#[schema(value_type = Vec<PaymentMethodType>)]
|
#[schema(value_type = Vec<PaymentMethodType>)]
|
||||||
pub wallets: Vec<api_enums::PaymentMethodType>,
|
pub wallets: Vec<api_enums::PaymentMethodType>,
|
||||||
/// Merchant connector details used to make payments.
|
/// Merchant connector details used to make payments.
|
||||||
|
#[schema(value_type = Option<MerchantConnectorDetailsWrap>)]
|
||||||
pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
|
pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1796,6 +1828,7 @@ pub struct PaymentsCancelRequest {
|
|||||||
/// The reason for the payment cancel
|
/// The reason for the payment cancel
|
||||||
pub cancellation_reason: Option<String>,
|
pub cancellation_reason: Option<String>,
|
||||||
/// Merchant connector details used to make payments.
|
/// Merchant connector details used to make payments.
|
||||||
|
#[schema(value_type = MerchantConnectorDetailsWrap)]
|
||||||
pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
|
pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -45,6 +45,7 @@ pub struct RefundRequest {
|
|||||||
pub metadata: Option<pii::SecretSerdeValue>,
|
pub metadata: Option<pii::SecretSerdeValue>,
|
||||||
|
|
||||||
/// Merchant connector details used to make payments.
|
/// Merchant connector details used to make payments.
|
||||||
|
#[schema(value_type = Option<MerchantConnectorDetailsWrap>)]
|
||||||
pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
|
pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -205,6 +205,7 @@ pub struct CurrencyCountryFlowFilter {
|
|||||||
pub country: Option<HashSet<api_models::enums::CountryAlpha2>>,
|
pub country: Option<HashSet<api_models::enums::CountryAlpha2>>,
|
||||||
pub not_available_flows: Option<NotAvailableFlows>,
|
pub not_available_flows: Option<NotAvailableFlows>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Copy, Clone, Default)]
|
#[derive(Debug, Deserialize, Copy, Clone, Default)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct NotAvailableFlows {
|
pub struct NotAvailableFlows {
|
||||||
|
|||||||
@ -29,7 +29,7 @@ Use the following base URLs when making requests to the APIs:
|
|||||||
| Environment | Base URL |
|
| Environment | Base URL |
|
||||||
|---------------|------------------------------------|
|
|---------------|------------------------------------|
|
||||||
| Sandbox | <https://sandbox.hyperswitch.io> |
|
| Sandbox | <https://sandbox.hyperswitch.io> |
|
||||||
| Production | Coming Soon! |
|
| Production | <https://api.hyperswitch.io> |
|
||||||
|
|
||||||
## Authentication
|
## Authentication
|
||||||
|
|
||||||
@ -39,9 +39,9 @@ You may authenticate all API requests with Hyperswitch server by providing the a
|
|||||||
the request Authorization header.
|
the request Authorization header.
|
||||||
|
|
||||||
| Key | Description |
|
| Key | Description |
|
||||||
|---------------|-----------------------------------------------------------------------------------------------|
|
|-----------------|-----------------------------------------------------------------------------------------------|
|
||||||
| Sandbox | Private key. Used to authenticate all API requests from your merchant server |
|
| api-key | Private key. Used to authenticate all API requests from your merchant server |
|
||||||
| Production | Unique identifier for your account. Used to authenticate API requests from your app's client |
|
| publishable key | Unique identifier for your account. Used to authenticate API requests from your app's client |
|
||||||
|
|
||||||
Never share your secret api keys. Keep them guarded and secure.
|
Never share your secret api keys. Keep them guarded and secure.
|
||||||
"#,
|
"#,
|
||||||
@ -65,15 +65,16 @@ Never share your secret api keys. Keep them guarded and secure.
|
|||||||
crate::routes::refunds::refunds_retrieve,
|
crate::routes::refunds::refunds_retrieve,
|
||||||
crate::routes::refunds::refunds_update,
|
crate::routes::refunds::refunds_update,
|
||||||
crate::routes::refunds::refunds_list,
|
crate::routes::refunds::refunds_list,
|
||||||
crate::routes::admin::merchant_account_create,
|
// Commenting this out as these are admin apis and not to be used by the merchant
|
||||||
crate::routes::admin::retrieve_merchant_account,
|
// crate::routes::admin::merchant_account_create,
|
||||||
crate::routes::admin::update_merchant_account,
|
// crate::routes::admin::retrieve_merchant_account,
|
||||||
crate::routes::admin::delete_merchant_account,
|
// crate::routes::admin::update_merchant_account,
|
||||||
crate::routes::admin::payment_connector_create,
|
// crate::routes::admin::delete_merchant_account,
|
||||||
crate::routes::admin::payment_connector_retrieve,
|
// crate::routes::admin::payment_connector_create,
|
||||||
crate::routes::admin::payment_connector_list,
|
// crate::routes::admin::payment_connector_retrieve,
|
||||||
crate::routes::admin::payment_connector_update,
|
// crate::routes::admin::payment_connector_list,
|
||||||
crate::routes::admin::payment_connector_delete,
|
// crate::routes::admin::payment_connector_update,
|
||||||
|
// crate::routes::admin::payment_connector_delete,
|
||||||
crate::routes::mandates::get_mandate,
|
crate::routes::mandates::get_mandate,
|
||||||
crate::routes::mandates::revoke_mandate,
|
crate::routes::mandates::revoke_mandate,
|
||||||
crate::routes::payments::payments_create,
|
crate::routes::payments::payments_create,
|
||||||
@ -114,6 +115,7 @@ Never share your secret api keys. Keep them guarded and secure.
|
|||||||
crate::types::api::admin::MerchantAccountUpdate,
|
crate::types::api::admin::MerchantAccountUpdate,
|
||||||
crate::types::api::admin::MerchantAccountDeleteResponse,
|
crate::types::api::admin::MerchantAccountDeleteResponse,
|
||||||
crate::types::api::admin::MerchantConnectorDeleteResponse,
|
crate::types::api::admin::MerchantConnectorDeleteResponse,
|
||||||
|
crate::types::api::admin::MerchantConnectorResponse,
|
||||||
crate::types::api::customers::CustomerRequest,
|
crate::types::api::customers::CustomerRequest,
|
||||||
crate::types::api::customers::CustomerDeleteResponse,
|
crate::types::api::customers::CustomerDeleteResponse,
|
||||||
crate::types::api::payment_methods::PaymentMethodCreate,
|
crate::types::api::payment_methods::PaymentMethodCreate,
|
||||||
@ -148,10 +150,25 @@ Never share your secret api keys. Keep them guarded and secure.
|
|||||||
api_models::enums::DisputeStage,
|
api_models::enums::DisputeStage,
|
||||||
api_models::enums::DisputeStatus,
|
api_models::enums::DisputeStatus,
|
||||||
api_models::enums::CountryAlpha2,
|
api_models::enums::CountryAlpha2,
|
||||||
|
api_models::enums::FrmAction,
|
||||||
|
api_models::enums::FrmPreferredFlowTypes,
|
||||||
api_models::admin::MerchantConnectorCreate,
|
api_models::admin::MerchantConnectorCreate,
|
||||||
|
api_models::admin::MerchantConnectorUpdate,
|
||||||
|
api_models::admin::PrimaryBusinessDetails,
|
||||||
|
api_models::admin::FrmConfigs,
|
||||||
api_models::admin::PaymentMethodsEnabled,
|
api_models::admin::PaymentMethodsEnabled,
|
||||||
|
api_models::admin::MerchantConnectorDetailsWrap,
|
||||||
|
api_models::admin::MerchantConnectorDetails,
|
||||||
api_models::disputes::DisputeResponse,
|
api_models::disputes::DisputeResponse,
|
||||||
|
api_models::disputes::DisputeResponsePaymentsRetrieve,
|
||||||
api_models::payments::AddressDetails,
|
api_models::payments::AddressDetails,
|
||||||
|
api_models::payments::BankDebitData,
|
||||||
|
api_models::payments::AliPayRedirection,
|
||||||
|
api_models::payments::MbWayRedirection,
|
||||||
|
api_models::payments::MobilePayRedirection,
|
||||||
|
api_models::payments::WeChatPayRedirection,
|
||||||
|
api_models::payments::BankDebitBilling,
|
||||||
|
api_models::payments::CryptoData,
|
||||||
api_models::payments::Address,
|
api_models::payments::Address,
|
||||||
api_models::payments::BankRedirectData,
|
api_models::payments::BankRedirectData,
|
||||||
api_models::payments::BankRedirectBilling,
|
api_models::payments::BankRedirectBilling,
|
||||||
@ -172,6 +189,7 @@ Never share your secret api keys. Keep them guarded and secure.
|
|||||||
api_models::payments::Card,
|
api_models::payments::Card,
|
||||||
api_models::payments::CustomerAcceptance,
|
api_models::payments::CustomerAcceptance,
|
||||||
api_models::payments::PaymentsRequest,
|
api_models::payments::PaymentsRequest,
|
||||||
|
api_models::payments::PaymentsCreateRequest,
|
||||||
api_models::payments::PaymentsResponse,
|
api_models::payments::PaymentsResponse,
|
||||||
api_models::payments::PaymentsStartRequest,
|
api_models::payments::PaymentsStartRequest,
|
||||||
api_models::payments::PaymentRetrieveBody,
|
api_models::payments::PaymentRetrieveBody,
|
||||||
|
|||||||
@ -158,9 +158,9 @@ pub async fn delete_merchant_account(
|
|||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
post,
|
post,
|
||||||
path = "/accounts/{account_id}/connectors",
|
path = "/accounts/{account_id}/connectors",
|
||||||
request_body = MerchantConnector,
|
request_body = MerchantConnectorCreate,
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Merchant Connector Created", body = MerchantConnector),
|
(status = 200, description = "Merchant Connector Created", body = MerchantConnectorResponse),
|
||||||
(status = 400, description = "Missing Mandatory fields"),
|
(status = 400, description = "Missing Mandatory fields"),
|
||||||
),
|
),
|
||||||
tag = "Merchant Connector Account",
|
tag = "Merchant Connector Account",
|
||||||
@ -198,7 +198,7 @@ pub async fn payment_connector_create(
|
|||||||
("connector_id" = i32, Path, description = "The unique identifier for the Merchant Connector")
|
("connector_id" = i32, Path, description = "The unique identifier for the Merchant Connector")
|
||||||
),
|
),
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Merchant Connector retrieved successfully", body = MerchantConnector),
|
(status = 200, description = "Merchant Connector retrieved successfully", body = MerchantConnectorResponse),
|
||||||
(status = 404, description = "Merchant Connector does not exist in records"),
|
(status = 404, description = "Merchant Connector does not exist in records"),
|
||||||
(status = 401, description = "Unauthorized request")
|
(status = 401, description = "Unauthorized request")
|
||||||
),
|
),
|
||||||
@ -242,7 +242,7 @@ pub async fn payment_connector_retrieve(
|
|||||||
("account_id" = String, Path, description = "The unique identifier for the merchant account"),
|
("account_id" = String, Path, description = "The unique identifier for the merchant account"),
|
||||||
),
|
),
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Merchant Connector list retrieved successfully", body = Vec<MerchantConnector>),
|
(status = 200, description = "Merchant Connector list retrieved successfully", body = Vec<MerchantConnectorResponse>),
|
||||||
(status = 404, description = "Merchant Connector does not exist in records"),
|
(status = 404, description = "Merchant Connector does not exist in records"),
|
||||||
(status = 401, description = "Unauthorized request")
|
(status = 401, description = "Unauthorized request")
|
||||||
),
|
),
|
||||||
@ -275,13 +275,13 @@ pub async fn payment_connector_list(
|
|||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
post,
|
post,
|
||||||
path = "/accounts/{account_id}/connectors/{connector_id}",
|
path = "/accounts/{account_id}/connectors/{connector_id}",
|
||||||
request_body = MerchantConnector,
|
request_body = MerchantConnectorUpdate,
|
||||||
params(
|
params(
|
||||||
("account_id" = String, Path, description = "The unique identifier for the merchant account"),
|
("account_id" = String, Path, description = "The unique identifier for the merchant account"),
|
||||||
("connector_id" = i32, Path, description = "The unique identifier for the Merchant Connector")
|
("connector_id" = i32, Path, description = "The unique identifier for the Merchant Connector")
|
||||||
),
|
),
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Merchant Connector Updated", body = MerchantConnector),
|
(status = 200, description = "Merchant Connector Updated", body = MerchantConnectorResponse),
|
||||||
(status = 404, description = "Merchant Connector does not exist in records"),
|
(status = 404, description = "Merchant Connector does not exist in records"),
|
||||||
(status = 401, description = "Unauthorized request")
|
(status = 401, description = "Unauthorized request")
|
||||||
),
|
),
|
||||||
|
|||||||
@ -11,7 +11,7 @@ use crate::{
|
|||||||
types::api::disputes as dispute_types,
|
types::api::disputes as dispute_types,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Diputes - Retrieve Dispute
|
/// Disputes - Retrieve Dispute
|
||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
get,
|
get,
|
||||||
path = "/disputes/{dispute_id}",
|
path = "/disputes/{dispute_id}",
|
||||||
@ -47,7 +47,7 @@ pub async fn retrieve_dispute(
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Diputes - List Disputes
|
/// Disputes - List Disputes
|
||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
get,
|
get,
|
||||||
path = "/disputes/list",
|
path = "/disputes/list",
|
||||||
@ -90,7 +90,7 @@ pub async fn retrieve_disputes_list(
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Diputes - Accept Dispute
|
/// Disputes - Accept Dispute
|
||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
get,
|
get,
|
||||||
path = "/disputes/accept/{dispute_id}",
|
path = "/disputes/accept/{dispute_id}",
|
||||||
@ -126,7 +126,7 @@ pub async fn accept_dispute(
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Diputes - Submit Dispute Evidence
|
/// Disputes - Submit Dispute Evidence
|
||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
post,
|
post,
|
||||||
path = "/disputes/evidence",
|
path = "/disputes/evidence",
|
||||||
|
|||||||
@ -48,7 +48,7 @@ pub async fn create_payment_method_api(
|
|||||||
/// To filter and list the applicable payment methods for a particular Merchant ID
|
/// To filter and list the applicable payment methods for a particular Merchant ID
|
||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
get,
|
get,
|
||||||
path = "/payment_methods/{account_id}",
|
path = "/account/payment_methods",
|
||||||
params (
|
params (
|
||||||
("account_id" = String, Path, description = "The unique identifier for the merchant account"),
|
("account_id" = String, Path, description = "The unique identifier for the merchant account"),
|
||||||
("accepted_country" = Vec<String>, Query, description = "The two-letter ISO currency code"),
|
("accepted_country" = Vec<String>, Query, description = "The two-letter ISO currency code"),
|
||||||
@ -96,7 +96,7 @@ pub async fn list_payment_method_api(
|
|||||||
/// To filter and list the applicable payment methods for a particular Customer ID
|
/// To filter and list the applicable payment methods for a particular Customer ID
|
||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
get,
|
get,
|
||||||
path = "/payment_methods/{customer_id}",
|
path = "/customer/{customer_id}/payment_methods",
|
||||||
params (
|
params (
|
||||||
("customer_id" = String, Path, description = "The unique identifier for the customer account"),
|
("customer_id" = String, Path, description = "The unique identifier for the customer account"),
|
||||||
("accepted_country" = Vec<String>, Query, description = "The two-letter ISO currency code"),
|
("accepted_country" = Vec<String>, Query, description = "The two-letter ISO currency code"),
|
||||||
|
|||||||
@ -18,7 +18,7 @@ use crate::{
|
|||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
post,
|
post,
|
||||||
path = "/payments",
|
path = "/payments",
|
||||||
request_body=PaymentsRequest,
|
request_body=PaymentsCreateRequest,
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Payment created", body = PaymentsResponse),
|
(status = 200, description = "Payment created", body = PaymentsResponse),
|
||||||
(status = 400, description = "Missing Mandatory fields")
|
(status = 400, description = "Missing Mandatory fields")
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
pub use api_models::admin::{
|
pub use api_models::admin::{
|
||||||
MerchantAccountCreate, MerchantAccountDeleteResponse, MerchantAccountResponse,
|
MerchantAccountCreate, MerchantAccountDeleteResponse, MerchantAccountResponse,
|
||||||
MerchantAccountUpdate, MerchantConnectorCreate, MerchantConnectorDeleteResponse,
|
MerchantAccountUpdate, MerchantConnectorCreate, MerchantConnectorDeleteResponse,
|
||||||
MerchantConnectorDetails, MerchantConnectorDetailsWrap, MerchantConnectorId, MerchantDetails,
|
MerchantConnectorDetails, MerchantConnectorDetailsWrap, MerchantConnectorId,
|
||||||
MerchantId, PaymentMethodsEnabled, RoutingAlgorithm, StraightThroughAlgorithm, ToggleKVRequest,
|
MerchantConnectorResponse, MerchantDetails, MerchantId, PaymentMethodsEnabled,
|
||||||
ToggleKVResponse, WebhookDetails,
|
RoutingAlgorithm, StraightThroughAlgorithm, ToggleKVRequest, ToggleKVResponse, WebhookDetails,
|
||||||
};
|
};
|
||||||
use common_utils::ext_traits::ValueExt;
|
use common_utils::ext_traits::ValueExt;
|
||||||
|
|
||||||
|
|||||||
@ -462,3 +462,50 @@ pub fn operation_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStre
|
|||||||
let input = syn::parse_macro_input!(input as syn::DeriveInput);
|
let input = syn::parse_macro_input!(input as syn::DeriveInput);
|
||||||
macros::operation_derive_inner(input).unwrap_or_else(|err| err.to_compile_error().into())
|
macros::operation_derive_inner(input).unwrap_or_else(|err| err.to_compile_error().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generates different schemas with the ability to mark few fields as mandatory for certain schema
|
||||||
|
/// Usage
|
||||||
|
/// ```
|
||||||
|
/// #[derive(PolymorphicSchema)]
|
||||||
|
/// #[generate_schemas(PaymentsCreateRequest, PaymentsConfirmRequest)]
|
||||||
|
/// struct PaymentsRequest {
|
||||||
|
/// #[mandatory_in(PaymentsCreateRequest)]
|
||||||
|
/// amount: Option<u64>,
|
||||||
|
/// #[mandatory_in(PaymentsCreateRequest)]
|
||||||
|
/// currency: Option<String>,
|
||||||
|
/// payment_method: String,
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// This will create two structs `PaymentsCreateRequest` and `PaymentsConfirmRequest` as follows
|
||||||
|
/// It will retain all the other attributes that are used in the original struct, and only consume
|
||||||
|
/// the #[mandatory_in] attribute to generate schemas
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #[derive(utoipa::ToSchema)]
|
||||||
|
/// struct PaymentsCreateRequest {
|
||||||
|
/// #[schema(required = true)]
|
||||||
|
/// amount: Option<u64>,
|
||||||
|
///
|
||||||
|
/// #[schema(required = true)]
|
||||||
|
/// currency: Option<String>,
|
||||||
|
///
|
||||||
|
/// payment_method: String,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// #[derive(utoipa::ToSchema)]
|
||||||
|
/// struct PaymentsConfirmRequest {
|
||||||
|
/// amount: Option<u64>,
|
||||||
|
/// currency: Option<String>,
|
||||||
|
/// payment_method: String,
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
#[proc_macro_derive(PolymorphicSchema, attributes(mandatory_in, generate_schemas))]
|
||||||
|
pub fn polymorphic_schema(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
|
let input = syn::parse_macro_input!(input as syn::DeriveInput);
|
||||||
|
|
||||||
|
macros::polymorphic_macro_derive_inner(input)
|
||||||
|
.unwrap_or_else(|error| error.into_compile_error())
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
pub(crate) mod api_error;
|
pub(crate) mod api_error;
|
||||||
pub(crate) mod diesel;
|
pub(crate) mod diesel;
|
||||||
mod helpers;
|
pub(crate) mod generate_schema;
|
||||||
pub(crate) mod operation;
|
pub(crate) mod operation;
|
||||||
|
|
||||||
|
mod helpers;
|
||||||
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::DeriveInput;
|
use syn::DeriveInput;
|
||||||
@ -12,6 +14,7 @@ pub(crate) use self::{
|
|||||||
diesel::{
|
diesel::{
|
||||||
diesel_enum_attribute_inner, diesel_enum_derive_inner, diesel_enum_text_derive_inner,
|
diesel_enum_attribute_inner, diesel_enum_derive_inner, diesel_enum_text_derive_inner,
|
||||||
},
|
},
|
||||||
|
generate_schema::polymorphic_macro_derive_inner,
|
||||||
operation::operation_derive_inner,
|
operation::operation_derive_inner,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
140
crates/router_derive/src/macros/generate_schema.rs
Normal file
140
crates/router_derive/src/macros/generate_schema.rs
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
use syn::{self, parse_quote, punctuated::Punctuated, Token};
|
||||||
|
|
||||||
|
use crate::macros::helpers;
|
||||||
|
|
||||||
|
/// Parse schemas from attribute
|
||||||
|
/// Example
|
||||||
|
///
|
||||||
|
/// #[mandatory_in(PaymentsCreateRequest, PaymentsUpdateRequest)]
|
||||||
|
/// would return
|
||||||
|
///
|
||||||
|
/// [PaymentsCreateRequest, PaymentsUpdateRequest]
|
||||||
|
fn get_inner_path_ident(attribute: &syn::Attribute) -> syn::Result<Vec<syn::Ident>> {
|
||||||
|
Ok(attribute
|
||||||
|
.parse_args_with(Punctuated::<syn::Ident, Token![,]>::parse_terminated)?
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Vec<_>>())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_struct_fields(data: syn::Data) -> syn::Result<Punctuated<syn::Field, syn::token::Comma>> {
|
||||||
|
if let syn::Data::Struct(syn::DataStruct {
|
||||||
|
fields: syn::Fields::Named(syn::FieldsNamed { ref named, .. }),
|
||||||
|
..
|
||||||
|
}) = data
|
||||||
|
{
|
||||||
|
Ok(named.to_owned())
|
||||||
|
} else {
|
||||||
|
Err(syn::Error::new(
|
||||||
|
proc_macro2::Span::call_site(),
|
||||||
|
"This macro cannot be used on structs with no fields",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn polymorphic_macro_derive_inner(
|
||||||
|
input: syn::DeriveInput,
|
||||||
|
) -> syn::Result<proc_macro2::TokenStream> {
|
||||||
|
let schemas_to_create =
|
||||||
|
helpers::get_metadata_inner::<syn::Ident>("generate_schemas", &input.attrs)?;
|
||||||
|
|
||||||
|
let fields = get_struct_fields(input.data)
|
||||||
|
.map_err(|error| syn::Error::new(proc_macro2::Span::call_site(), error))?;
|
||||||
|
|
||||||
|
// Go through all the fields and create a mapping of required fields for a schema
|
||||||
|
// PaymentsCreate -> ["amount","currency"]
|
||||||
|
// This will be stored in a hashset
|
||||||
|
// mandatory_hashset -> ((PaymentsCreate, amount), (PaymentsCreate,currency))
|
||||||
|
let mut mandatory_hashset = HashSet::<(syn::Ident, syn::Ident)>::new();
|
||||||
|
let mut other_fields_hm = HashMap::<syn::Field, Vec<syn::Attribute>>::new();
|
||||||
|
|
||||||
|
fields.iter().for_each(|field| {
|
||||||
|
// Partition the attributes of a field into two vectors
|
||||||
|
// One with #[mandatory_in] attributes present
|
||||||
|
// Rest of the attributes ( include only the schema attribute, serde is not required)
|
||||||
|
let (mandatory_attribute, other_attributes) = field
|
||||||
|
.attrs
|
||||||
|
.iter()
|
||||||
|
.partition::<Vec<_>, _>(|attribute| attribute.path.is_ident("mandatory_in"));
|
||||||
|
|
||||||
|
// Other attributes ( schema ) are to be printed as is
|
||||||
|
other_attributes
|
||||||
|
.iter()
|
||||||
|
.filter(|attribute| attribute.path.is_ident("schema") || attribute.path.is_ident("doc"))
|
||||||
|
.for_each(|attribute| {
|
||||||
|
// Since attributes will be modified, the field should not contain any attributes
|
||||||
|
// So create a field, with previous attributes removed
|
||||||
|
let mut field_without_attributes = field.clone();
|
||||||
|
field_without_attributes.attrs.clear();
|
||||||
|
|
||||||
|
other_fields_hm
|
||||||
|
.entry(field_without_attributes.to_owned())
|
||||||
|
.or_insert(vec![])
|
||||||
|
.push(attribute.to_owned().to_owned());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Mandatory attributes are to be inserted into hashset
|
||||||
|
// The hashset will store it in this format
|
||||||
|
// (PaymentsCreateRequest, "amount")
|
||||||
|
// (PaymentsConfirmRequest, "currency")
|
||||||
|
//
|
||||||
|
// For these attributes, we need to later add #[schema(required = true)] attribute
|
||||||
|
_ = mandatory_attribute
|
||||||
|
.iter()
|
||||||
|
// Filter only #[mandatory_in] attributes
|
||||||
|
.map(|&attribute| get_inner_path_ident(attribute))
|
||||||
|
.try_for_each(|schemas| {
|
||||||
|
let res = schemas
|
||||||
|
.map_err(|error| syn::Error::new(proc_macro2::Span::call_site(), error))?
|
||||||
|
.iter()
|
||||||
|
.filter_map(|schema| field.ident.to_owned().zip(Some(schema.to_owned())))
|
||||||
|
.collect::<HashSet<_>>();
|
||||||
|
|
||||||
|
mandatory_hashset.extend(res);
|
||||||
|
Ok::<_, syn::Error>(())
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let schemas = schemas_to_create
|
||||||
|
.iter()
|
||||||
|
.map(|schema| {
|
||||||
|
let fields = other_fields_hm
|
||||||
|
.iter()
|
||||||
|
.flat_map(|(field, value)| {
|
||||||
|
let mut attributes = value
|
||||||
|
.iter()
|
||||||
|
.map(|attribute| quote::quote!(#attribute))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
// If the field is required for this schema, then add
|
||||||
|
// #[schema(required = true)] for this field
|
||||||
|
let required_attribute: syn::Attribute =
|
||||||
|
parse_quote!(#[schema(required = true)]);
|
||||||
|
|
||||||
|
// Can be none, because tuple fields have no ident
|
||||||
|
field.ident.to_owned().and_then(|field_ident| {
|
||||||
|
mandatory_hashset
|
||||||
|
.contains(&(field_ident, schema.to_owned()))
|
||||||
|
.then(|| attributes.push(quote::quote!(#required_attribute)))
|
||||||
|
});
|
||||||
|
|
||||||
|
quote::quote! {
|
||||||
|
#(#attributes)*
|
||||||
|
#field,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
quote::quote! {
|
||||||
|
#[derive(utoipa::ToSchema)]
|
||||||
|
pub struct #schema {
|
||||||
|
#(#fields)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
Ok(quote::quote! {
|
||||||
|
#(#schemas)*
|
||||||
|
})
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user