doc: update openapi (#453)

Co-authored-by: Sangamesh <sangamesh.kulkarni@juspay.in>
Co-authored-by: dracarys18 <karthikey.hegde@juspay.in>
Co-authored-by: bernard eugine <bernard.eugine@bernard.eugine-MacBookPro>
Co-authored-by: Abhishek Marrivagu <abhi.codes10@gmail.com>
This commit is contained in:
bernard-eugine
2023-01-30 16:56:37 +05:30
committed by GitHub
parent d3ef24e8e9
commit ec2f4ba257
40 changed files with 3314 additions and 283 deletions

View File

@ -211,7 +211,7 @@ pub struct WebhookDetails {
}
#[derive(Debug, Serialize, ToSchema)]
pub struct DeleteResponse {
pub struct DeleteMerchantAccountResponse {
/// The identifier for the Merchant Account
#[schema(max_length = 255, example = "y3oqhf46pyzuxjbcn2giaqnb44")]
pub merchant_id: String,

View File

@ -326,6 +326,7 @@ pub enum FutureUsage {
strum::Display,
strum::EnumString,
frunk::LabelledGeneric,
ToSchema,
)]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
@ -467,6 +468,7 @@ pub enum RoutingAlgorithm {
Custom,
}
/// The status of the mandate, which indicates whether it can be used to initiate a payment
#[derive(
Clone,
Copy,
@ -479,6 +481,7 @@ pub enum RoutingAlgorithm {
strum::Display,
strum::EnumString,
frunk::LabelledGeneric,
ToSchema,
)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]

View File

@ -1,5 +1,6 @@
use masking::Secret;
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
use crate::{enums as api_enums, payments};
@ -8,30 +9,54 @@ pub struct MandateId {
pub mandate_id: String,
}
#[derive(Default, Debug, Deserialize, Serialize)]
#[derive(Default, Debug, Deserialize, Serialize, ToSchema)]
pub struct MandateRevokedResponse {
/// The identifier for mandate
pub mandate_id: String,
/// The status for mandates
#[schema(value_type = MandateStatus)]
pub status: api_enums::MandateStatus,
}
#[derive(Default, Debug, Deserialize, Serialize)]
#[derive(Default, Debug, Deserialize, Serialize, ToSchema)]
pub struct MandateResponse {
/// The identifier for mandate
pub mandate_id: String,
/// The status for mandates
#[schema(value_type = MandateStatus)]
pub status: api_enums::MandateStatus,
/// The identifier for payment method
pub payment_method_id: String,
/// The payment method
pub payment_method: String,
/// The card details for mandate
pub card: Option<MandateCardDetails>,
/// Details about the customers acceptance
#[schema(value_type = Option<CustomerAcceptance>)]
pub customer_acceptance: Option<payments::CustomerAcceptance>,
}
#[derive(Default, Debug, Deserialize, Serialize)]
#[derive(Default, Debug, Deserialize, Serialize, ToSchema)]
pub struct MandateCardDetails {
/// The last 4 digits of card
pub last4_digits: Option<String>,
/// The expiry month of card
#[schema(value_type = Option<String>)]
pub card_exp_month: Option<Secret<String>>,
/// The expiry year of card
#[schema(value_type = Option<String>)]
pub card_exp_year: Option<Secret<String>>,
/// The card holder name
#[schema(value_type = Option<String>)]
pub card_holder_name: Option<Secret<String>>,
/// The token from card locker
#[schema(value_type = Option<String>)]
pub card_token: Option<Secret<String>>,
/// The card scheme network for the particular card
pub scheme: Option<String>,
/// The country code in in which the card was issued
pub issuer_country: Option<String>,
#[schema(value_type = Option<String>)]
/// A unique identifier alias to identify a particular card
pub card_fingerprint: Option<Secret<String>>,
}

View File

@ -6,76 +6,185 @@ use utoipa::ToSchema;
use crate::enums as api_enums;
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
#[serde(deny_unknown_fields)]
pub struct CreatePaymentMethod {
/// The type of payment method use for the payment.
#[schema(value_type = PaymentMethodType,example = "card")]
pub payment_method: api_enums::PaymentMethodType,
/// This is a sub-category of payment method.
#[schema(value_type = Option<PaymentMethodSubType>,example = "credit_card")]
pub payment_method_type: Option<api_enums::PaymentMethodSubType>,
/// The name of the bank/ provider issuing the payment method to the end user
#[schema(example = "Citibank")]
pub payment_method_issuer: Option<String>,
/// A standard code representing the issuer of payment method
#[schema(value_type = Option<PaymentMethodIssuerCode>,example = "jp_applepay")]
pub payment_method_issuer_code: Option<api_enums::PaymentMethodIssuerCode>,
/// Card Details
#[schema(example = json!({
"card_number": "4111111145551142",
"card_exp_month": "10",
"card_exp_year": "25",
"card_holder_name": "John Doe"}))]
pub card: Option<CardDetail>,
/// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.
#[schema(value_type = Option<Object>,example = json!({ "city": "NY", "unit": "245" }))]
pub metadata: Option<serde_json::Value>,
/// The unique identifier of the customer.
#[schema(example = "cus_meowerunwiuwiwqw")]
pub customer_id: Option<String>,
}
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
#[serde(deny_unknown_fields)]
pub struct UpdatePaymentMethod {
/// Card Details
#[schema(example = json!({
"card_number": "4111111145551142",
"card_exp_month": "10",
"card_exp_year": "25",
"card_holder_name": "John Doe"}))]
pub card: Option<CardDetail>,
// Add more payment method update field in future
/// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.
#[schema(value_type = Option<Object>,example = json!({ "city": "NY", "unit": "245" }))]
pub metadata: Option<serde_json::Value>,
}
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
#[serde(deny_unknown_fields)]
pub struct CardDetail {
/// Card Number
#[schema(value_type = String,example = "4111111145551142")]
pub card_number: masking::Secret<String, pii::CardNumber>,
/// Card Expiry Month
#[schema(value_type = String,example = "10")]
pub card_exp_month: masking::Secret<String>,
/// Card Expiry Year
#[schema(value_type = String,example = "25")]
pub card_exp_year: masking::Secret<String>,
/// Card Holder Name
#[schema(value_type = String,example = "John Doe")]
pub card_holder_name: Option<masking::Secret<String>>,
}
#[derive(Debug, serde::Deserialize, serde::Serialize)]
#[derive(Debug, serde::Deserialize, serde::Serialize, ToSchema)]
pub struct PaymentMethodResponse {
/// Unique identifier for a merchant
#[schema(example = "merchant_1671528864")]
pub merchant_id: String,
/// The unique identifier of the customer.
#[schema(example = "cus_meowerunwiuwiwqw")]
pub customer_id: Option<String>,
/// The unique identifier of the Payment method
#[schema(example = "card_rGK4Vi5iSW70MY7J2mIy")]
pub payment_method_id: String,
/// The type of payment method use for the payment.
#[schema(value_type = PaymentMethodType,example = "card")]
pub payment_method: api_enums::PaymentMethodType,
/// This is a sub-category of payment method.
#[schema(value_type = Option<PaymentMethodSubType>,example = "credit_card")]
pub payment_method_type: Option<api_enums::PaymentMethodSubType>,
/// The name of the bank/ provider issuing the payment method to the end user
#[schema(example = "Citibank")]
pub payment_method_issuer: Option<String>,
/// A standard code representing the issuer of payment method
#[schema(value_type = Option<PaymentMethodIssuerCode>,example = "jp_applepay")]
pub payment_method_issuer_code: Option<api_enums::PaymentMethodIssuerCode>,
/// Card details from card locker
#[schema(example = json!({"last4": "1142","exp_month": "03","exp_year": "2030"}))]
pub card: Option<CardDetailFromLocker>,
/// Indicates whether the payment method is eligible for recurring payments
#[schema(example = true)]
pub recurring_enabled: bool,
/// Indicates whether the payment method is eligible for installment payments
#[schema(example = true)]
pub installment_payment_enabled: bool,
/// Type of payment experience enabled with the connector
#[schema(value_type = Option<Vec<PaymentExperience>>,example = json!(["redirect_to_url"]))]
pub payment_experience: Option<Vec<PaymentExperience>>,
/// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.
#[schema(value_type = Option<Object>,example = json!({ "city": "NY", "unit": "245" }))]
pub metadata: Option<serde_json::Value>,
/// A timestamp (ISO 8601 code) that determines when the customer was created
#[schema(value_type = Option<PrimitiveDateTime>,example = "2023-01-18T11:04:09.922Z")]
#[serde(default, with = "common_utils::custom_serde::iso8601::option")]
pub created: Option<time::PrimitiveDateTime>,
}
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
pub struct CardDetailFromLocker {
pub scheme: Option<String>,
pub issuer_country: Option<String>,
pub last4_digits: Option<String>,
#[serde(skip)]
#[schema(value_type=Option<String>)]
pub card_number: Option<masking::Secret<String, pii::CardNumber>>,
#[schema(value_type=Option<String>)]
pub expiry_month: Option<masking::Secret<String>>,
#[schema(value_type=Option<String>)]
pub expiry_year: Option<masking::Secret<String>>,
#[schema(value_type=Option<String>)]
pub card_token: Option<masking::Secret<String>>,
#[schema(value_type=Option<String>)]
pub card_holder_name: Option<masking::Secret<String>>,
#[schema(value_type=Option<String>)]
pub card_fingerprint: Option<masking::Secret<String>>,
}
//List Payment Method
#[derive(Debug, serde::Serialize, Default)]
#[derive(Debug, serde::Serialize, Default, ToSchema)]
#[serde(deny_unknown_fields)]
pub struct ListPaymentMethodRequest {
/// This is a 15 minute expiry token which shall be used from the client to authenticate and perform sessions from the SDK
#[schema(max_length = 30, min_length = 30, example = "secret_k2uj3he2893ein2d")]
pub client_secret: Option<String>,
/// The two-letter ISO currency code
#[schema(example = json!(["US", "UK", "IN"]))]
pub accepted_countries: Option<Vec<String>>,
/// The three-letter ISO currency code
#[schema(value_type = Option<Vec<Currency>>,example = json!(["USD", "EUR"]))]
pub accepted_currencies: Option<Vec<api_enums::Currency>>,
/// Filter by amount
#[schema(example = 60)]
pub amount: Option<i64>,
/// Indicates whether the payment method is eligible for recurring payments
#[schema(example = true)]
pub recurring_enabled: Option<bool>,
/// Indicates whether the payment method is eligible for installment payments
#[schema(example = true)]
pub installment_payment_enabled: Option<bool>,
}
@ -168,25 +277,78 @@ fn set_or_reject_duplicate<T, E: de::Error>(
}
}
#[derive(Debug, serde::Serialize)]
#[derive(Debug, serde::Serialize, ToSchema)]
pub struct ListPaymentMethodResponse {
/// Redirect URL of the merchant
#[schema(example = "https://www.google.com")]
pub redirect_url: Option<String>,
/// Information about the payment method
#[schema(value_type = Vec<ListPaymentMethod>,example = json!(
[
{
"payment_method": "wallet",
"payment_experience": null,
"payment_method_issuers": [
"labore magna ipsum",
"aute"
]
}
]
))]
pub payment_methods: HashSet<ListPaymentMethod>,
}
#[derive(Eq, PartialEq, Hash, Debug, serde::Deserialize)]
#[derive(Eq, PartialEq, Hash, Debug, serde::Deserialize, ToSchema)]
pub struct ListPaymentMethod {
/// The type of payment method use for the payment.
#[schema(value_type = PaymentMethodType,example = "card")]
pub payment_method: api_enums::PaymentMethodType,
/// This is a sub-category of payment method.
#[schema(value_type = Option<Vec<PaymentMethodSubType>>,example = json!(["credit_card"]))]
pub payment_method_types: Option<Vec<api_enums::PaymentMethodSubType>>,
/// The name of the bank/ provider issuing the payment method to the end user
#[schema(example = json!(["Citibank"]))]
pub payment_method_issuers: Option<Vec<String>>,
/// A standard code representing the issuer of payment method
#[schema(value_type = Option<Vec<PaymentMethodIssuerCode>>,example = json!(["jp_applepay"]))]
pub payment_method_issuer_code: Option<Vec<api_enums::PaymentMethodIssuerCode>>,
/// List of payment schemes accepted or has the processing capabilities of the processor
#[schema(example = json!(["MASTER", "VISA", "DINERS"]))]
pub payment_schemes: Option<Vec<String>>,
/// List of Countries accepted or has the processing capabilities of the processor
#[schema(example = json!(["US", "UK", "IN"]))]
pub accepted_countries: Option<Vec<String>>,
/// List of currencies accepted or has the processing capabilities of the processor
#[schema(value_type = Option<Vec<Currency>>,example = json!(["USD", "EUR"]))]
pub accepted_currencies: Option<Vec<api_enums::Currency>>,
/// Minimum amount supported by the processor. To be represented in the lowest denomination of
/// the target currency (For example, for USD it should be in cents)
#[schema(example = 60000)]
pub minimum_amount: Option<i64>,
/// Maximum amount supported by the processor. To be represented in the lowest denomination of
/// the target currency (For example, for USD it should be in cents)
#[schema(example = 1)]
pub maximum_amount: Option<i64>,
/// Boolean to enable recurring payments / mandates. Default is true.
#[schema(example = true)]
pub recurring_enabled: bool,
/// Boolean to enable installment / EMI / BNPL payments. Default is true.
#[schema(example = true)]
pub installment_payment_enabled: bool,
/// Type of payment experience enabled with the connector
#[schema(example = json!(["redirect_to_url"]))]
pub payment_experience: Option<Vec<PaymentExperience>>,
}
@ -217,31 +379,86 @@ impl serde::Serialize for ListPaymentMethod {
}
}
#[derive(Debug, serde::Serialize)]
#[derive(Debug, serde::Serialize, ToSchema)]
pub struct ListCustomerPaymentMethodsResponse {
/// List of enabled payment methods for a customer
#[schema(value_type = Vec<ListPaymentMethod>,example = json!(
[
{
"payment_method": "wallet",
"payment_experience": null,
"payment_method_issuers": [
"labore magna ipsum",
"aute"
]
}
]
))]
pub enabled_payment_methods: HashSet<ListPaymentMethod>,
/// List of payment methods for customer
pub customer_payment_methods: Vec<CustomerPaymentMethod>,
}
#[derive(Debug, serde::Serialize)]
#[derive(Debug, serde::Serialize, ToSchema)]
pub struct DeletePaymentMethodResponse {
/// The unique identifier of the Payment method
#[schema(example = "card_rGK4Vi5iSW70MY7J2mIy")]
pub payment_method_id: String,
/// Whether payment method was deleted or not
#[schema(example = true)]
pub deleted: bool,
}
#[derive(Debug, serde::Serialize)]
#[derive(Debug, serde::Serialize, ToSchema)]
pub struct CustomerPaymentMethod {
/// Token for payment method in temporary card locker which gets refreshed often
#[schema(example = "7ebf443f-a050-4067-84e5-e6f6d4800aef")]
pub payment_token: String,
/// The unique identifier of the customer.
#[schema(example = "cus_meowerunwiuwiwqw")]
pub customer_id: String,
/// The type of payment method use for the payment.
#[schema(value_type = PaymentMethodType,example = "card")]
pub payment_method: api_enums::PaymentMethodType,
/// This is a sub-category of payment method.
#[schema(value_type = Option<PaymentMethodSubType>,example = "credit_card")]
pub payment_method_type: Option<api_enums::PaymentMethodSubType>,
/// The name of the bank/ provider issuing the payment method to the end user
#[schema(example = "Citibank")]
pub payment_method_issuer: Option<String>,
/// A standard code representing the issuer of payment method
#[schema(value_type = Option<PaymentMethodIssuerCode>,example = "jp_applepay")]
pub payment_method_issuer_code: Option<api_enums::PaymentMethodIssuerCode>,
/// Indicates whether the payment method is eligible for recurring payments
#[schema(example = true)]
pub recurring_enabled: bool,
/// Indicates whether the payment method is eligible for installment payments
#[schema(example = true)]
pub installment_payment_enabled: bool,
/// Type of payment experience enabled with the connector
#[schema(value_type = Option<Vec<PaymentExperience>>,example = json!(["redirect_to_url"]))]
pub payment_experience: Option<Vec<PaymentExperience>>,
/// Card details from card locker
#[schema(example = json!({"last4": "1142","exp_month": "03","exp_year": "2030"}))]
pub card: Option<CardDetailFromLocker>,
/// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.
#[schema(value_type = Option<Object>,example = json!({ "city": "NY", "unit": "245" }))]
pub metadata: Option<serde_json::Value>,
/// A timestamp (ISO 8601 code) that determines when the customer was created
#[schema(value_type = Option<PrimitiveDateTime>,example = "2023-01-18T11:04:09.922Z")]
#[serde(default, with = "common_utils::custom_serde::iso8601::option")]
pub created: Option<time::PrimitiveDateTime>,
}

View File

@ -96,7 +96,7 @@ pub struct PaymentsRequest {
/// Provide a reference to a stored payment method
#[schema(example = "187282ab-40ef-47a9-9206-5099ba31e432")]
pub payment_token: Option<String>,
/// This is used when payment is to be confirmed and the card is not saved
#[schema(value_type = Option<String>)]
pub card_cvc: Option<Secret<String>>,
/// The shipping address for the payment
@ -301,7 +301,7 @@ pub struct OnlineMandate {
}
#[derive(Default, Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
pub struct CCard {
pub struct Card {
/// The card number
#[schema(value_type = String, example = "4242424242424242")]
pub card_number: Secret<String, pii::CardNumber>,
@ -375,17 +375,13 @@ pub enum PayLaterData {
}
#[derive(Debug, Clone, Eq, PartialEq, Default, serde::Deserialize, serde::Serialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum PaymentMethod {
#[serde(rename(deserialize = "card"))]
Card(CCard),
Card(Card),
#[default]
#[serde(rename(deserialize = "bank_transfer"))]
BankTransfer,
#[serde(rename(deserialize = "wallet"))]
Wallet(WalletData),
#[serde(rename(deserialize = "pay_later"))]
PayLater(PayLaterData),
#[serde(rename(deserialize = "paypal"))]
Paypal,
}
@ -399,7 +395,7 @@ pub struct WalletData {
}
#[derive(Eq, PartialEq, Clone, Debug, serde::Serialize)]
pub struct CCardResponse {
pub struct CardResponse {
last4: String,
exp_month: String,
exp_year: String,
@ -408,7 +404,7 @@ pub struct CCardResponse {
#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize)]
pub enum PaymentMethodDataResponse {
#[serde(rename = "card")]
Card(CCardResponse),
Card(CardResponse),
#[serde(rename(deserialize = "bank_transfer"))]
BankTransfer,
Wallet(WalletData),
@ -936,8 +932,8 @@ impl From<PaymentsCaptureRequest> for PaymentsResponse {
}
}
impl From<CCard> for CCardResponse {
fn from(card: CCard) -> Self {
impl From<Card> for CardResponse {
fn from(card: Card) -> Self {
let card_number_length = card.card_number.peek().clone().len();
Self {
last4: card.card_number.peek().clone()[card_number_length - 4..card_number_length]
@ -951,7 +947,7 @@ impl From<CCard> for CCardResponse {
impl From<PaymentMethod> for PaymentMethodDataResponse {
fn from(payment_method_data: PaymentMethod) -> Self {
match payment_method_data {
PaymentMethod::Card(card) => Self::Card(CCardResponse::from(card)),
PaymentMethod::Card(card) => Self::Card(CardResponse::from(card)),
PaymentMethod::BankTransfer => Self::BankTransfer,
PaymentMethod::PayLater(pay_later_data) => Self::PayLater(pay_later_data),
PaymentMethod::Wallet(wallet_data) => Self::Wallet(wallet_data),

View File

@ -67,18 +67,29 @@ pub enum RefundType {
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize, ToSchema)]
pub struct RefundResponse {
/// The identifier for refund
pub refund_id: String,
/// The identifier for payment
pub payment_id: String,
/// The refund amount, which should be less than or equal to the total 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
pub amount: i64,
/// The three-letter ISO currency code
pub currency: String,
/// An arbitrary string attached to the object. Often useful for displaying to users and your customer support executive
pub reason: Option<String>,
/// The status for refund
pub status: RefundStatus,
/// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object
#[schema(value_type = Option<Object>)]
pub metadata: Option<serde_json::Value>,
/// The error message
pub error_message: Option<String>,
/// The code for the error
pub error_code: Option<String>,
/// The timestamp at which refund is created
#[serde(with = "common_utils::custom_serde::iso8601::option")]
pub created_at: Option<PrimitiveDateTime>,
/// The timestamp at which refund is updated
#[serde(with = "common_utils::custom_serde::iso8601::option")]
pub updated_at: Option<PrimitiveDateTime>,
}
@ -114,11 +125,13 @@ pub struct RefundListRequest {
pub created_gte: Option<PrimitiveDateTime>,
}
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize, ToSchema)]
pub struct RefundListResponse {
/// The list of refund response
pub data: Vec<RefundResponse>,
}
/// The status for refunds
#[derive(Debug, Eq, Clone, PartialEq, Default, Deserialize, Serialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum RefundStatus {

View File

@ -19,6 +19,7 @@ olap = []
oltp = []
production = []
kv_store = []
openapi = ["olap", "oltp"]
[dependencies]

View File

@ -1,5 +1,5 @@
use router::{
configs::settings::{CmdLineConf, Settings, Subcommand},
configs::settings::{CmdLineConf, Settings},
core::errors::{ApplicationError, ApplicationResult},
logger,
};
@ -8,6 +8,10 @@ use router::{
async fn main() -> ApplicationResult<()> {
// get commandline config before initializing config
let cmd_line = <CmdLineConf as clap::Parser>::parse();
#[cfg(feature = "openapi")]
{
use router::configs::settings::Subcommand;
if let Some(Subcommand::GenerateOpenapiSpec) = cmd_line.subcommand {
let file_path = "openapi/generated.json";
#[allow(clippy::expect_used)]
@ -21,6 +25,7 @@ async fn main() -> ApplicationResult<()> {
println!("Successfully saved OpenAPI specification file at '{file_path}'");
return Ok(());
}
}
#[allow(clippy::expect_used)]
let conf = Settings::with_config_path(cmd_line.config_path)

View File

@ -73,7 +73,7 @@ pub enum StripePaymentMethodDetails {
BankTransfer,
}
impl From<StripeCard> for payments::CCard {
impl From<StripeCard> for payments::Card {
fn from(card: StripeCard) -> Self {
Self {
card_number: card.number,
@ -87,7 +87,7 @@ impl From<StripeCard> for payments::CCard {
impl From<StripePaymentMethodDetails> for payments::PaymentMethod {
fn from(item: StripePaymentMethodDetails) -> Self {
match item {
StripePaymentMethodDetails::Card(card) => Self::Card(payments::CCard::from(card)),
StripePaymentMethodDetails::Card(card) => Self::Card(payments::Card::from(card)),
StripePaymentMethodDetails::BankTransfer => Self::BankTransfer,
}
}

View File

@ -69,7 +69,7 @@ pub enum StripePaymentMethodDetails {
BankTransfer,
}
impl From<StripeCard> for payments::CCard {
impl From<StripeCard> for payments::Card {
fn from(card: StripeCard) -> Self {
Self {
card_number: card.number,
@ -83,7 +83,7 @@ impl From<StripeCard> for payments::CCard {
impl From<StripePaymentMethodDetails> for payments::PaymentMethod {
fn from(item: StripePaymentMethodDetails) -> Self {
match item {
StripePaymentMethodDetails::Card(card) => Self::Card(payments::CCard::from(card)),
StripePaymentMethodDetails::Card(card) => Self::Card(payments::Card::from(card)),
StripePaymentMethodDetails::BankTransfer => Self::BankTransfer,
}
}

View File

@ -25,6 +25,7 @@ pub struct CmdLineConf {
#[derive(clap::Parser)]
pub enum Subcommand {
#[cfg(feature = "openapi")]
/// Generate the OpenAPI specification file from code.
GenerateOpenapiSpec,
}

View File

@ -37,7 +37,7 @@ pub trait PaymentsRequestData {
fn get_billing(&self) -> Result<&api::Address, Error>;
fn get_billing_country(&self) -> Result<String, Error>;
fn get_billing_phone(&self) -> Result<&api::PhoneDetails, Error>;
fn get_card(&self) -> Result<api::CCard, Error>;
fn get_card(&self) -> Result<api::Card, Error>;
}
impl PaymentsRequestData for types::PaymentsAuthorizeRouterData {
@ -56,7 +56,7 @@ impl PaymentsRequestData for types::PaymentsAuthorizeRouterData {
.ok_or_else(missing_field_err("billing.address.country"))
}
fn get_card(&self) -> Result<api::CCard, Error> {
fn get_card(&self) -> Result<api::Card, Error> {
match self.request.payment_method_data.clone() {
api::PaymentMethod::Card(card) => Ok(card),
_ => Err(missing_field_err("card")()),
@ -86,7 +86,7 @@ pub trait CardData {
fn get_card_cvc(&self) -> String;
}
impl CardData for api::CCard {
impl CardData for api::Card {
fn get_card_number(&self) -> String {
self.card_number.peek().clone()
}

View File

@ -133,7 +133,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentsRequest {
fn make_card_request(
address: &types::PaymentAddress,
req: &types::PaymentsAuthorizeData,
ccard: &api_models::CCard,
ccard: &api_models::Card,
) -> Result<PaymentsRequest, error_stack::Report<errors::ConnectorError>> {
let card_number = ccard.card_number.peek().as_ref();
let expiry_year = ccard.card_exp_year.peek().clone();

View File

@ -198,14 +198,14 @@ pub async fn merchant_account_update(
pub async fn merchant_account_delete(
db: &dyn StorageInterface,
merchant_id: String,
) -> RouterResponse<api::DeleteResponse> {
) -> RouterResponse<api::DeleteMerchantAccountResponse> {
let is_deleted = db
.delete_merchant_account_by_merchant_id(&merchant_id)
.await
.map_err(|error| {
error.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
})?;
let response = api::DeleteResponse {
let response = api::DeleteMerchantAccountResponse {
merchant_id,
deleted: is_deleted,
};

View File

@ -36,7 +36,7 @@ pub trait Vaultable: Sized {
) -> CustomResult<(Self, SupplementaryVaultData), errors::VaultError>;
}
impl Vaultable for api::CCard {
impl Vaultable for api::Card {
fn get_value1(&self, _customer_id: Option<String>) -> CustomResult<String, errors::VaultError> {
let value1 = api::TokenizedCardValue1 {
card_number: self.card_number.peek().clone(),
@ -201,7 +201,7 @@ impl Vaultable for api::PaymentMethod {
match (value1, value2) {
(VaultPaymentMethod::Card(mvalue1), VaultPaymentMethod::Card(mvalue2)) => {
let (card, supp_data) = api::CCard::from_values(mvalue1, mvalue2)?;
let (card, supp_data) = api::Card::from_values(mvalue1, mvalue2)?;
Ok((Self::Card(card), supp_data))
}
(VaultPaymentMethod::Wallet(mvalue1), VaultPaymentMethod::Wallet(mvalue2)) => {

View File

@ -16,6 +16,7 @@ pub mod routes;
pub mod scheduler;
mod middleware;
#[cfg(feature = "openapi")]
pub mod openapi;
pub mod services;
pub mod types;

View File

@ -1,51 +1,97 @@
#[derive(utoipa::OpenApi)]
#[openapi(
info(
title = "Juspay Router - API Documentation",
title = "Hyperswitch - API Documentation",
contact(
name = "Juspay Support",
url = "https://juspay.io",
email = "support@juspay.in"
name = "Hyperswitch Support",
url = "https://hyperswitch.io",
email = "hyperswitch@juspay.in"
),
// terms_of_service = "https://www.juspay.io/terms",
description = r#"
## Get started
Juspay Router provides a collection of APIs that enable you to process and manage payments.
Hyperswitch provides a collection of APIs that enable you to process and manage payments.
Our APIs accept and return JSON in the HTTP body, and return standard HTTP response codes.
You can consume the APIs directly using your favorite HTTP/REST library.
We have a testing environment referred to "sandbox", which you can setup to test API calls without
affecting production data.
affecting production data. Currently, our sandbox environment is live while our production environment is under development and will be available soon. You can sign up on our Dashboard to get API keys to access Hyperswitch API.
### Base URLs
### Environment
Use the following base URLs when making requests to the APIs:
| Environment | Base URL |
|---------------|------------------------------------------------------|
|---------------|------------------------------------|
| Sandbox | <https://sandbox.hyperswitch.io> |
| Production | <https://router.juspay.io> |
| Production | Coming Soon! |
## Authentication
When you sign up on our [dashboard](https://app.hyperswitch.io) and create a merchant
account, you are given a secret key (also referred as api-key).
You may authenticate all API requests with Juspay server by providing the appropriate key in the
account, you are given a secret key (also referred as api-key) and a publishable key.
You may authenticate all API requests with Hyperswitch server by providing the appropriate key in the
request Authorization header.
| Key | Description |
|---------------|-----------------------------------------------------------------------------------------------|
| Sandbox | 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 apps client |
Never share your secret api keys. Keep them guarded and secure.
"#,
),
servers(
(url = "https://sandbox.hyperswitch.io", description = "Sandbox Environment"),
(url = "https://router.juspay.io", description = "Production Environment")
(url = "https://sandbox.hyperswitch.io", description = "Sandbox Environment")
),
tags(
(name = "Merchant Account"),// , description = "Create and manage merchant accounts"),
(name = "Merchant Connector Account"),// , description = "Create and manage merchant connector accounts"),
(name = "Payments"),// , description = "Create and manage one-time payments, recurring payments and mandates"),
(name = "Refunds"),// , description = "Create and manage refunds for successful payments"),
(name = "Mandates"),// , description = "Manage mandates"),
(name = "Customers"),// , description = "Create and manage customers"),
(name = "Payment Methods")// , description = "Create and manage payment methods of customers")
),
paths(
crate::routes::refunds::refunds_create,
crate::routes::refunds::refunds_retrieve,
crate::routes::refunds::refunds_update,
crate::routes::refunds::refunds_list,
crate::routes::refunds::refunds_create,
crate::routes::admin::merchant_account_create,
crate::routes::payments::payments_create
crate::routes::admin::retrieve_merchant_account,
crate::routes::admin::update_merchant_account,
crate::routes::admin::delete_merchant_account,
crate::routes::admin::payment_connector_create,
crate::routes::admin::payment_connector_retrieve,
crate::routes::admin::payment_connector_list,
crate::routes::admin::payment_connector_update,
crate::routes::admin::payment_connector_delete,
crate::routes::mandates::get_mandate,
crate::routes::mandates::revoke_mandate,
crate::routes::payments::payments_create,
// crate::routes::payments::payments_start,
crate::routes::payments::payments_retrieve,
crate::routes::payments::payments_update,
crate::routes::payments::payments_confirm,
crate::routes::payments::payments_capture,
crate::routes::payments::payments_connector_session,
// crate::routes::payments::payments_redirect_response,
crate::routes::payments::payments_cancel,
crate::routes::payments::payments_list,
crate::routes::payment_methods::create_payment_method_api,
crate::routes::payment_methods::list_payment_method_api,
crate::routes::payment_methods::list_customer_payment_method_api,
crate::routes::payment_methods::payment_method_retrieve_api,
crate::routes::payment_methods::payment_method_update_api,
crate::routes::payment_methods::payment_method_delete_api,
crate::routes::customers::customers_create,
crate::routes::customers::customers_retrieve,
crate::routes::customers::customers_update,
crate::routes::customers::customers_delete,
),
components(schemas(
crate::types::api::refunds::RefundRequest,
@ -54,10 +100,20 @@ Never share your secret api keys. Keep them guarded and secure.
crate::types::api::refunds::RefundStatus,
crate::types::api::refunds::RefundUpdateRequest,
crate::types::api::admin::CreateMerchantAccount,
crate::types::api::admin::DeleteResponse,
crate::types::api::admin::DeleteMerchantAccountResponse,
crate::types::api::admin::DeleteMcaResponse,
crate::types::api::customers::CustomerRequest,
crate::types::api::customers::CustomerDeleteResponse,
crate::types::api::payment_methods::CreatePaymentMethod,
crate::types::api::payment_methods::PaymentMethodResponse,
crate::types::api::payment_methods::ListPaymentMethod,
crate::types::api::payment_methods::CustomerPaymentMethod,
crate::types::api::payment_methods::ListPaymentMethodResponse,
crate::types::api::payment_methods::ListCustomerPaymentMethodsResponse,
crate::types::api::payment_methods::DeletePaymentMethodResponse,
crate::types::api::payment_methods::UpdatePaymentMethod,
crate::types::api::payment_methods::CardDetailFromLocker,
crate::types::api::payment_methods::CardDetail,
api_models::customers::CustomerResponse,
api_models::enums::RoutingAlgorithm,
api_models::enums::PaymentMethodType,
@ -72,6 +128,8 @@ Never share your secret api keys. Keep them guarded and secure.
api_models::enums::Connector,
api_models::enums::PaymentMethodType,
api_models::enums::SupportedWallets,
api_models::enums::PaymentMethodIssuerCode,
api_models::enums::MandateStatus,
api_models::admin::PaymentConnectorCreate,
api_models::admin::PaymentMethods,
api_models::payments::AddressDetails,
@ -92,7 +150,7 @@ Never share your secret api keys. Keep them guarded and secure.
api_models::payments::AcceptanceType,
api_models::payments::MandateAmountData,
api_models::payments::OnlineMandate,
api_models::payments::CCard,
api_models::payments::Card,
api_models::payments::CustomerAcceptance,
api_models::payments::PaymentsRequest,
api_models::payments::PaymentsResponse,
@ -115,6 +173,10 @@ Never share your secret api keys. Keep them guarded and secure.
api_models::payments::PaymentListConstraints,
api_models::payments::PaymentListResponse,
api_models::refunds::RefundListRequest,
api_models::refunds::RefundListResponse,
api_models::mandates::MandateRevokedResponse,
api_models::mandates::MandateResponse,
api_models::mandates::MandateCardDetails,
crate::types::api::admin::MerchantAccountResponse,
crate::types::api::admin::MerchantConnectorId,
crate::types::api::admin::MerchantDetails,

View File

@ -8,17 +8,20 @@ use crate::{
types::api::admin,
};
/// Merchant Account - Create
// ### Merchant Account - Create
///
/// Create a new account for a merchant and the merchant could be a seller or retailer or client who likes to receive and send payments.
#[utoipa::path(
post,
path = "/account",
path = "/accounts",
request_body= CreateMerchantAccount,
responses(
(status = 200, description = "Merchant Account Created", body = MerchantAccountResponse),
(status = 400, description = "Invalid data")
)
),
tag = "Merchant Account",
operation_id = "Create a Merchant Account"
)]
#[instrument(skip_all, fields(flow = ?Flow::MerchantsAccountCreate))]
pub async fn merchant_account_create(
@ -36,16 +39,20 @@ pub async fn merchant_account_create(
.await
}
/// Merchant Account - Retrieve
// Merchant Account - Retrieve
///
/// Retrieve a merchant account details.
#[utoipa::path(
get,
path = "/account/{account_id}",
path = "/accounts/{account_id}",
params (("account_id" = String, Path, description = "The unique identifier for the merchant account")),
responses(
(status = 200, description = "Merchant Account Retrieved", body = MerchantAccountResponse),
(status = 404, description = "Merchant account not found")
)
),
tag = "Merchant Account",
operation_id = "Retrieve a Merchant Account"
)]
#[instrument(skip_all, fields(flow = ?Flow::MerchantsAccountRetrieve))]
pub async fn retrieve_merchant_account(
@ -67,17 +74,21 @@ pub async fn retrieve_merchant_account(
.await
}
/// Merchant Account - Update
/// Update a merchant account details.
// Merchant Account - Update
///
/// To update an existing merchant account. Helpful in updating merchant details such as email, contact details, or other configuration details like webhook, routing algorithm etc
#[utoipa::path(
post,
path = "/account/{account_id}",
path = "/accounts/{account_id}",
request_body = CreateMerchantAccount,
params (("account_id" = String, Path, description = "The unique identifier for the merchant account")),
responses(
(status = 200, description = "Merchant Account Updated", body = MerchantAccountResponse),
(status = 404, description = "Merchant account not found")
)
),
tag = "Merchant Account",
operation_id = "Update a Merchant Account"
)]
#[instrument(skip_all, fields(flow = ?Flow::MerchantsAccountUpdate))]
pub async fn update_merchant_account(
@ -97,16 +108,20 @@ pub async fn update_merchant_account(
.await
}
/// Merchant Account - Delete
/// Delete a merchant account details.
// Merchant Account - Delete
///
/// To delete a merchant account
#[utoipa::path(
delete,
path = "/account/{account_id}",
path = "/accounts/{account_id}",
params (("account_id" = String, Path, description = "The unique identifier for the merchant account")),
responses(
(status = 200, description = "Merchant Account Deleted", body = DeleteResponse),
(status = 200, description = "Merchant Account Deleted", body = DeleteMerchantAccountResponse),
(status = 404, description = "Merchant account not found")
)
),
tag = "Merchant Account",
operation_id = "Delete a Merchant Account"
)]
#[instrument(skip_all, fields(flow = ?Flow::MerchantsAccountDelete))]
// #[delete("/{id}")]
@ -129,17 +144,20 @@ pub async fn delete_merchant_account(
.await
}
/// PaymentsConnectors - Create
// PaymentsConnectors - Create
///
/// Create a new Payment Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialized services like Fraud / Accounting etc."
#[utoipa::path(
post,
path = "/account/{account_id}/connectors",
path = "/accounts/{account_id}/connectors",
request_body = PaymentConnectorCreate,
responses(
(status = 200, description = "Payment Connector Created", body = PaymentConnectorCreate),
(status = 400, description = "Missing Mandatory fields")
)
(status = 400, description = "Missing Mandatory fields"),
),
tag = "Merchant Connector Account",
operation_id = "Create a Merchant Connector"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentConnectorsCreate))]
pub async fn payment_connector_create(
@ -159,12 +177,13 @@ pub async fn payment_connector_create(
.await
}
/// Payment Connector - Retrieve
// Payment Connector - Retrieve
///
/// Retrieve Payment Connector Details
#[utoipa::path(
get,
path = "/account/{account_id}/connectors/{connector_id}",
path = "/accounts/{account_id}/connectors/{connector_id}",
params(
("account_id" = String, Path, description = "The unique identifier for the merchant account"),
("connector_id" = i32, Path, description = "The unique identifier for the payment connector")
@ -173,7 +192,9 @@ pub async fn payment_connector_create(
(status = 200, description = "Payment Connector retrieved successfully", body = PaymentConnectorCreate),
(status = 404, description = "Payment Connector does not exist in records"),
(status = 401, description = "Unauthorized request")
)
),
tag = "Merchant Connector Account",
operation_id = "Retrieve a Merchant Connector"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentConnectorsRetrieve))]
pub async fn payment_connector_retrieve(
@ -199,12 +220,13 @@ pub async fn payment_connector_retrieve(
.await
}
/// Payment Connector - List
// Payment Connector - List
///
/// List Payment Connector Details for the merchant
#[utoipa::path(
get,
path = "/account/{account_id}/connectors",
path = "/accounts/{account_id}/connectors",
params(
("account_id" = String, Path, description = "The unique identifier for the merchant account"),
),
@ -212,7 +234,9 @@ pub async fn payment_connector_retrieve(
(status = 200, description = "Payment Connector list retrieved successfully", body = Vec<PaymentConnectorCreate>),
(status = 404, description = "Payment Connector does not exist in records"),
(status = 401, description = "Unauthorized request")
)
),
tag = "Merchant Connector Account",
operation_id = "List all Merchant Connectors"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentConnectorsList))]
pub async fn payment_connector_list(
@ -231,12 +255,13 @@ pub async fn payment_connector_list(
.await
}
/// Payment Connector - Update
// Payment Connector - Update
///
/// To update an existing Payment Connector. Helpful in enabling / disabling different payment methods and other settings for the connector etc
/// To update an existing Payment Connector. Helpful in enabling / disabling different payment methods and other settings for the connector etc.
#[utoipa::path(
post,
path = "/account/{account_id}/connectors/{connector_id}",
path = "/accounts/{account_id}/connectors/{connector_id}",
request_body = PaymentConnectorCreate,
params(
("account_id" = String, Path, description = "The unique identifier for the merchant account"),
@ -246,7 +271,9 @@ pub async fn payment_connector_list(
(status = 200, description = "Payment Connector Updated", body = PaymentConnectorCreate),
(status = 404, description = "Payment Connector does not exist in records"),
(status = 401, description = "Unauthorized request")
)
),
tag = "Merchant Connector Account",
operation_id = "Update a Merchant Connector"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentConnectorsUpdate))]
pub async fn payment_connector_update(
@ -268,11 +295,13 @@ pub async fn payment_connector_update(
.await
}
/// Payment Connector - Delete
// Payment Connector - Delete
///
/// Delete or Detach a Payment Connector from Merchant Account
#[utoipa::path(
delete,
path = "/account/{account_id}/connectors/{connector_id}",
path = "/accounts/{account_id}/connectors/{connector_id}",
params(
("account_id" = String, Path, description = "The unique identifier for the merchant account"),
("connector_id" = i32, Path, description = "The unique identifier for the payment connector")
@ -281,7 +310,9 @@ pub async fn payment_connector_update(
(status = 200, description = "Payment Connector Deleted", body = DeleteMcaResponse),
(status = 404, description = "Payment Connector does not exist in records"),
(status = 401, description = "Unauthorized request")
)
),
tag = "Merchant Connector Account",
operation_id = "Delete a Merchant Connector"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentConnectorsDelete))]
pub async fn payment_connector_delete(

View File

@ -92,7 +92,7 @@ impl Payments {
)
.service(
web::resource("/{payment_id}/{merchant_id}/response/{connector}")
.route(web::get().to(payments_response)),
.route(web::get().to(payments_redirect_response)),
);
}
route

View File

@ -8,7 +8,8 @@ use crate::{
types::api::customers,
};
/// Create Customer
// Create Customer
///
/// Create a customer object and store the customer details to be reused for future payments. Incase the customer already exists in the system, this API will respond with the customer details.
#[utoipa::path(
@ -18,7 +19,9 @@ use crate::{
responses(
(status = 200, description = "Customer Created", body = CustomerResponse),
(status = 400, description = "Invalid data")
)
),
tag = "Customers",
operation_id = "Create a Customer"
)]
#[instrument(skip_all, fields(flow = ?Flow::CustomersCreate))]
pub async fn customers_create(
@ -36,7 +39,8 @@ pub async fn customers_create(
.await
}
/// Retrieve Customer
// Retrieve Customer
///
/// Retrieve a customer's details.
#[utoipa::path(
@ -46,7 +50,9 @@ pub async fn customers_create(
responses(
(status = 200, description = "Customer Retrieved", body = CustomerResponse),
(status = 404, description = "Customer was not found")
)
),
tag = "Customers",
operation_id = "Retrieve a Customer"
)]
#[instrument(skip_all, fields(flow = ?Flow::CustomersRetrieve))]
pub async fn customers_retrieve(
@ -75,7 +81,8 @@ pub async fn customers_retrieve(
.await
}
/// Update Customer
// Update Customer
///
/// Updates the customer's details in a customer object.
#[utoipa::path(
@ -86,7 +93,9 @@ pub async fn customers_retrieve(
responses(
(status = 200, description = "Customer was Updated", body = CustomerResponse),
(status = 404, description = "Customer was not found")
)
),
tag = "Customers",
operation_id = "Update a Customer"
)]
#[instrument(skip_all, fields(flow = ?Flow::CustomersUpdate))]
pub async fn customers_update(
@ -107,7 +116,8 @@ pub async fn customers_update(
.await
}
/// Delete Customer
// Delete Customer
///
/// Delete a customer record.
#[utoipa::path(
@ -117,7 +127,9 @@ pub async fn customers_update(
responses(
(status = 200, description = "Customer was Deleted", body = CustomerDeleteResponse),
(status = 404, description = "Customer was not found")
)
),
tag = "Customers",
operation_id = "Delete a Customer"
)]
#[instrument(skip_all, fields(flow = ?Flow::CustomersDelete))]
pub async fn customers_delete(

View File

@ -8,6 +8,23 @@ use crate::{
types::api::mandates,
};
// Mandates - Retrieve Mandate
///
/// Retrieve a mandate
#[utoipa::path(
get,
path = "/mandates/{mandate_id}",
params(
("mandate_id" = String, Path, description = "The identifier for mandate")
),
responses(
(status = 200, description = "The mandate was retrieved successfully", body = MandateResponse),
(status = 404, description = "Mandate does not exist in our records")
),
tag = "Mandates",
operation_id = "Retrieve a Mandate"
)]
#[instrument(skip_all, fields(flow = ?Flow::MandatesRetrieve))]
// #[get("/{id}")]
pub async fn get_mandate(
@ -28,6 +45,23 @@ pub async fn get_mandate(
.await
}
// Mandates - Revoke Mandate
///
/// Revoke a mandate
#[utoipa::path(
post,
path = "/mandates/revoke/{mandate_id}",
params(
("mandate_id" = String, Path, description = "The identifier for mandate")
),
responses(
(status = 200, description = "The mandate was revoked successfully", body = MandateRevokedResponse),
(status = 400, description = "Mandate does not exist in our records")
),
tag = "Mandates",
operation_id = "Revoke a Mandate"
)]
#[instrument(skip_all, fields(flow = ?Flow::MandatesRevoke))]
// #[post("/revoke/{id}")]
pub async fn revoke_mandate(

View File

@ -8,8 +8,22 @@ use crate::{
types::api::payment_methods::{self, PaymentMethodId},
};
// PaymentMethods - Create
///
/// To create a payment method against a customer object. In case of cards, this API could be used only by PCI compliant merchants
#[utoipa::path(
post,
path = "/payment_methods",
request_body = CreatePaymentMethod,
responses(
(status = 200, description = "Payment Method Created", body = PaymentMethodResponse),
(status = 400, description = "Invalid Data")
),
tag = "Payment Methods",
operation_id = "Create a Payment Method"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentMethodsCreate))]
// #[post("")]
pub async fn create_payment_method_api(
state: web::Data<AppState>,
req: HttpRequest,
@ -27,8 +41,31 @@ pub async fn create_payment_method_api(
.await
}
// List payment methods for a Merchant
///
/// To filter and list the applicable payment methods for a particular Merchant ID
#[utoipa::path(
get,
path = "/payment_methods/{account_id}",
params (
("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_currency" = Vec<Currency>, Path, description = "The three-letter ISO currency code"),
("minimum_amount" = i64, Query, description = "The minimum amount accepted for processing by the particular payment method."),
("maximum_amount" = i64, Query, description = "The maximum amount amount accepted for processing by the particular payment method."),
("recurring_payment_enabled" = bool, Query, description = "Indicates whether the payment method is eligible for recurring payments"),
("installment_payment_enabled" = bool, Query, description = "Indicates whether the payment method is eligible for installment payments"),
),
responses(
(status = 200, description = "Payment Methods retrieved", body = ListPaymentMethodResponse),
(status = 400, description = "Invalid Data"),
(status = 404, description = "Payment Methods does not exist in records")
),
tag = "Payment Methods",
operation_id = "List all Payment Methods for a Merchant"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentMethodsList))]
//#[get("{merchant_id}")]
pub async fn list_payment_method_api(
state: web::Data<AppState>,
req: HttpRequest,
@ -53,8 +90,31 @@ pub async fn list_payment_method_api(
.await
}
// List payment methods for a Customer
///
/// To filter and list the applicable payment methods for a particular Customer ID
#[utoipa::path(
get,
path = "/payment_methods/{customer_id}",
params (
("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_currency" = Vec<Currency>, Path, description = "The three-letter ISO currency code"),
("minimum_amount" = i64, Query, description = "The minimum amount accepted for processing by the particular payment method."),
("maximum_amount" = i64, Query, description = "The maximum amount amount accepted for processing by the particular payment method."),
("recurring_payment_enabled" = bool, Query, description = "Indicates whether the payment method is eligible for recurring payments"),
("installment_payment_enabled" = bool, Query, description = "Indicates whether the payment method is eligible for installment payments"),
),
responses(
(status = 200, description = "Payment Methods retrieved", body = ListCustomerPaymentMethodsResponse),
(status = 400, description = "Invalid Data"),
(status = 404, description = "Payment Methods does not exist in records")
),
tag = "Payment Methods",
operation_id = "List all Payment Methods for a Customer"
)]
#[instrument(skip_all, fields(flow = ?Flow::CustomerPaymentMethodsList))]
// #[get("/{customer_id}/payment_methods")]
pub async fn list_customer_payment_method_api(
state: web::Data<AppState>,
customer_id: web::Path<(String,)>,
@ -81,8 +141,24 @@ pub async fn list_customer_payment_method_api(
.await
}
// Payment Method - Retrieve
///
/// To retrieve a payment method
#[utoipa::path(
get,
path = "/payment_methods/{method_id}",
params (
("method_id" = String, Path, description = "The unique identifier for the Payment Method"),
),
responses(
(status = 200, description = "Payment Method retrieved", body = PaymentMethodResponse),
(status = 404, description = "Payment Method does not exist in records")
),
tag = "Payment Methods",
operation_id = "Retrieve a Payment method"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentMethodsRetrieve))]
// #[get("/{payment_method_id}")]
pub async fn payment_method_retrieve_api(
state: web::Data<AppState>,
req: HttpRequest,
@ -103,6 +179,24 @@ pub async fn payment_method_retrieve_api(
.await
}
// Payment Method - Update
///
/// To update an existing payment method attached to a customer object. This API is useful for use cases such as updating the card number for expired cards to prevent discontinuity in recurring payments
#[utoipa::path(
post,
path = "/payment_methods/{method_id}",
params (
("method_id" = String, Path, description = "The unique identifier for the Payment Method"),
),
request_body = UpdatePaymentMethod,
responses(
(status = 200, description = "Payment Method updated", body = PaymentMethodResponse),
(status = 404, description = "Payment Method does not exist in records")
),
tag = "Payment Methods",
operation_id = "Update a Payment method"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentMethodsUpdate))]
pub async fn payment_method_update_api(
state: web::Data<AppState>,
@ -129,8 +223,24 @@ pub async fn payment_method_update_api(
.await
}
// Payment Method - Delete
///
/// Delete payment method
#[utoipa::path(
delete,
path = "/payment_methods/{method_id}",
params (
("method_id" = String, Path, description = "The unique identifier for the Payment Method"),
),
responses(
(status = 200, description = "Payment Method deleted", body = DeletePaymentMethodResponse),
(status = 404, description = "Payment Method does not exist in records")
),
tag = "Payment Methods",
operation_id = "Delete a Payment method"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentMethodsDelete))]
// #[post("/{payment_method_id}/detach")]
pub async fn payment_method_delete_api(
state: web::Data<AppState>,
req: HttpRequest,

View File

@ -9,9 +9,10 @@ use crate::{
types::api::{self as api_types, enums as api_enums, payments as payment_types},
};
/// Payments - Create
// Payments - Create
///
/// To create a new payment, against a merchant API key
/// To process a payment you will have to create a payment, attach a payment method and confirm. Depending on the user journey you wish to achieve, you may opt to all the steps in a single request or in a sequence of API request using following APIs: (i) Payments - Update, (ii) Payments - Confirm, and (iii) Payments - Capture
#[utoipa::path(
post,
path = "/payments",
@ -19,7 +20,9 @@ use crate::{
responses(
(status = 200, description = "Payment created", body = PaymentsResponse),
(status = 400, description = "Missing Mandatory fields")
)
),
tag = "Payments",
operation_id = "Create a Payment"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentsCreate))]
// #[post("")]
@ -52,6 +55,24 @@ pub async fn payments_create(
.await
}
// /// Payments - Start
// ///
// /// The entry point for a payment which involves the redirection flow. This redirects the user to the authentication page
// #[utoipa::path(
// get,
// path = "/payments/start/{payment_id}/{merchant_id}/{attempt_id}",
// params(
// ("payment_id" = String, Path, description = "The identifier for payment"),
// ("merchant_id" = String, Path, description = "The identifier for merchant"),
// ("attempt_id" = String, Path, description = "The identifier for transaction")
// ),
// responses(
// (status = 200, description = "Redirects to the authentication page"),
// (status = 404, description = "No redirection found")
// ),
// tag = "Payments",
// operation_id = "Start a Redirection Payment"
// )]
#[instrument(skip(state), fields(flow = ?Flow::PaymentsStart))]
pub async fn payments_start(
state: web::Data<app::AppState>,
@ -83,6 +104,24 @@ pub async fn payments_start(
.await
}
// Payments - Retrieve
///
/// To retrieve the properties of a Payment. This may be used to get the status of a previously initiated payment or next action for an ongoing payment
#[utoipa::path(
get,
path = "/payments/{payment_id}",
params(
("payment_id" = String, Path, description = "The identifier for payment")
),
request_body=PaymentRetrieveBody,
responses(
(status = 200, description = "Gets the payment with final status", body = PaymentsResponse),
(status = 404, description = "No payment found")
),
tag = "Payments",
operation_id = "Retrieve a Payment"
)]
#[instrument(skip(state), fields(flow = ?Flow::PaymentsRetrieve))]
// #[get("/{payment_id}")]
pub async fn payments_retrieve(
@ -122,6 +161,24 @@ pub async fn payments_retrieve(
.await
}
// Payments - Update
///
/// To update the properties of a PaymentIntent object. This may include attaching a payment method, or attaching customer object or metadata fields after the Payment is created
#[utoipa::path(
post,
path = "/payments/{payment_id}",
params(
("payment_id" = String, Path, description = "The identifier for payment")
),
request_body=PaymentsRequest,
responses(
(status = 200, description = "Payment updated", body = PaymentsResponse),
(status = 400, description = "Missing mandatory fields")
),
tag = "Payments",
operation_id = "Update a Payment"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentsUpdate))]
// #[post("/{payment_id}")]
pub async fn payments_update(
@ -163,6 +220,24 @@ pub async fn payments_update(
.await
}
// Payments - Confirm
///
/// This API is to confirm the payment request and forward payment to the payment processor. This API provides more granular control upon when the API is forwarded to the payment processor. Alternatively you can confirm the payment within the Payments Create API
#[utoipa::path(
post,
path = "/payments/{payment_id}/confirm",
params(
("payment_id" = String, Path, description = "The identifier for payment")
),
request_body=PaymentsRequest,
responses(
(status = 200, description = "Payment confirmed", body = PaymentsResponse),
(status = 400, description = "Missing mandatory fields")
),
tag = "Payments",
operation_id = "Confirm a Payment"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentsConfirm))]
// #[post("/{payment_id}/confirm")]
pub async fn payments_confirm(
@ -205,6 +280,24 @@ pub async fn payments_confirm(
.await
}
// Payments - Capture
///
/// To capture the funds for an uncaptured payment
#[utoipa::path(
post,
path = "/payments/{payment_id}/capture",
params(
("payment_id" = String, Path, description = "The identifier for payment")
),
request_body=PaymentsCaptureRequest,
responses(
(status = 200, description = "Payment captured", body = PaymentsResponse),
(status = 400, description = "Missing mandatory fields")
),
tag = "Payments",
operation_id = "Capture a Payment"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentsCapture))]
// #[post("/{payment_id}/capture")]
pub async fn payments_capture(
@ -237,6 +330,21 @@ pub async fn payments_capture(
.await
}
// Payments - Session token
///
/// To create the session object or to get session token for wallets
#[utoipa::path(
post,
path = "/payments/session_tokens",
request_body=PaymentsSessionRequest,
responses(
(status = 200, description = "Payment session object created or session token was retrieved from wallets", body = PaymentsSessionResponse),
(status = 400, description = "Missing mandatory fields")
),
tag = "Payments",
operation_id = "Create Session tokens for a Payment"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentsSessionToken))]
pub async fn payments_connector_session(
state: web::Data<app::AppState>,
@ -270,8 +378,26 @@ pub async fn payments_connector_session(
.await
}
// /// Payments - Redirect response
// ///
// /// To get the payment response for redirect flows
// #[utoipa::path(
// post,
// path = "/payments/{payment_id}/{merchant_id}/response/{connector}",
// params(
// ("payment_id" = String, Path, description = "The identifier for payment"),
// ("merchant_id" = String, Path, description = "The identifier for merchant"),
// ("connector" = String, Path, description = "The name of the connector")
// ),
// responses(
// (status = 302, description = "Received payment redirect response"),
// (status = 400, description = "Missing mandatory fields")
// ),
// tag = "Payments",
// operation_id = "Get Redirect Response for a Payment"
// )]
#[instrument(skip_all)]
pub async fn payments_response(
pub async fn payments_redirect_response(
state: web::Data<app::AppState>,
req: actix_web::HttpRequest,
path: web::Path<(String, String, String)>,
@ -302,6 +428,24 @@ pub async fn payments_response(
.await
}
// Payments - Cancel
///
/// A Payment could can be cancelled when it is in one of these statuses: requires_payment_method, requires_capture, requires_confirmation, requires_customer_action
#[utoipa::path(
post,
path = "/payments/{payment_id}/cancel",
request_body=PaymentsCancelRequest,
params(
("payment_id" = String, Path, description = "The identifier for payment")
),
responses(
(status = 200, description = "Payment canceled"),
(status = 400, description = "Missing mandatory fields")
),
tag = "Payments",
operation_id = "Cancel a Payment"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentsCancel))]
// #[post("/{payment_id}/cancel")]
pub async fn payments_cancel(
@ -333,6 +477,31 @@ pub async fn payments_cancel(
.await
}
// Payments - List
///
/// To list the payments
#[utoipa::path(
get,
path = "/payments/list",
params(
("customer_id" = String, Query, description = "The identifier for the customer"),
("starting_after" = String, Query, description = "A cursor for use in pagination, fetch the next list after some object"),
("ending_before" = String, Query, description = "A cursor for use in pagination, fetch the previous list before some object"),
("limit" = i64, Query, description = "Limit on the number of objects to return"),
("created" = PrimitiveDateTime, Query, description = "The time at which payment is created"),
("created_lt" = PrimitiveDateTime, Query, description = "Time less than the payment created time"),
("created_gt" = PrimitiveDateTime, Query, description = "Time greater than the payment created time"),
("created_lte" = PrimitiveDateTime, Query, description = "Time less than or equals to the payment created time"),
("created_gte" = PrimitiveDateTime, Query, description = "Time greater than or equals to the payment created time")
),
responses(
(status = 200, description = "Received payment list"),
(status = 404, description = "No payments found")
),
tag = "Payments",
operation_id = "List all Payments"
)]
#[instrument(skip_all, fields(flow = ?Flow::PaymentsList))]
#[cfg(feature = "olap")]
// #[get("/list")]

View File

@ -8,7 +8,8 @@ use crate::{
types::api::refunds,
};
/// Refunds - Create
// Refunds - Create
///
/// To create a refund against an already processed payment
#[utoipa::path(
@ -18,7 +19,9 @@ use crate::{
responses(
(status = 200, description = "Refund created", body = RefundResponse),
(status = 400, description = "Missing Mandatory fields")
)
),
tag = "Refunds",
operation_id = "Create a Refund"
)]
#[instrument(skip_all, fields(flow = ?Flow::RefundsCreate))]
// #[post("")]
@ -37,9 +40,10 @@ pub async fn refunds_create(
.await
}
/// Refunds - Retrieve
// Refunds - Retrieve
///
/// To retrieve a refund against an already processed payment
/// To retrieve the properties of a Refund. This may be used to get the status of a previously initiated payment or next action for an ongoing payment
#[utoipa::path(
get,
path = "/refunds/{refund_id}",
@ -49,7 +53,9 @@ pub async fn refunds_create(
responses(
(status = 200, description = "Refund retrieved", body = RefundResponse),
(status = 404, description = "Refund does not exist in our records")
)
),
tag = "Refunds",
operation_id = "Retrieve a Refund"
)]
#[instrument(skip_all, fields(flow = ?Flow::RefundsRetrieve))]
// #[get("/{id}")]
@ -72,9 +78,10 @@ pub async fn refunds_retrieve(
.await
}
/// Refunds - Update
// Refunds - Update
///
/// To update a refund against an already processed payment
/// To update the properties of a Refund object. This may include attaching a reason for the refund or metadata fields
#[utoipa::path(
post,
path = "/refunds/{refund_id}",
@ -85,7 +92,9 @@ pub async fn refunds_retrieve(
responses(
(status = 200, description = "Refund updated", body = RefundResponse),
(status = 400, description = "Missing Mandatory fields")
)
),
tag = "Refunds",
operation_id = "Update a Refund"
)]
#[instrument(skip_all, fields(flow = ?Flow::RefundsUpdate))]
// #[post("/{id}")]
@ -108,7 +117,8 @@ pub async fn refunds_update(
.await
}
/// Refunds - List
// Refunds - List
///
/// To list the refunds associated with a payment_id or with the merchant, if payment_id is not provided
#[utoipa::path(
@ -126,7 +136,9 @@ pub async fn refunds_update(
responses(
(status = 200, description = "List of refunds", body = RefundListResponse),
(status = 404, description = "Refund does not exist in our records")
)
),
tag = "Refunds",
operation_id = "List all Refunds"
)]
#[instrument(skip_all, fields(flow = ?Flow::RefundsList))]
#[cfg(feature = "olap")]

View File

@ -1,7 +1,7 @@
pub use api_models::admin::{
CreateMerchantAccount, DeleteMcaResponse, DeleteResponse, MerchantAccountResponse,
MerchantConnectorId, MerchantDetails, MerchantId, PaymentConnectorCreate, PaymentMethods,
RoutingAlgorithm, WebhookDetails,
CreateMerchantAccount, DeleteMcaResponse, DeleteMerchantAccountResponse,
MerchantAccountResponse, MerchantConnectorId, MerchantDetails, MerchantId,
PaymentConnectorCreate, PaymentMethods, RoutingAlgorithm, WebhookDetails,
};
use crate::types::{storage, transformers::Foreign};

View File

@ -1,5 +1,5 @@
pub use api_models::payments::{
AcceptanceType, Address, AddressDetails, Amount, AuthenticationForStartResponse, CCard,
AcceptanceType, Address, AddressDetails, Amount, AuthenticationForStartResponse, Card,
CustomerAcceptance, MandateData, MandateTxnType, MandateType, MandateValidationFields,
NextAction, NextActionType, OnlineMandate, PayLaterData, PaymentIdType, PaymentListConstraints,
PaymentListResponse, PaymentMethod, PaymentMethodDataResponse, PaymentOp, PaymentRetrieveBody,
@ -182,8 +182,8 @@ mod payments_test {
use super::*;
#[allow(dead_code)]
fn card() -> CCard {
CCard {
fn card() -> Card {
Card {
card_number: "1234432112344321".to_string().into(),
card_exp_month: "12".to_string().into(),
card_exp_year: "99".to_string().into(),

View File

@ -33,7 +33,7 @@ fn construct_payment_router_data() -> types::PaymentsAuthorizeRouterData {
request: types::PaymentsAuthorizeData {
amount: 1000,
currency: enums::Currency::USD,
payment_method_data: types::api::PaymentMethod::Card(types::api::CCard {
payment_method_data: types::api::PaymentMethod::Card(types::api::Card {
card_number: Secret::new("4200000000000000".to_string()),
card_exp_month: Secret::new("10".to_string()),
card_exp_year: Secret::new("2025".to_string()),
@ -150,7 +150,7 @@ async fn payments_create_failure() {
types::PaymentsResponseData,
> = connector.connector.get_connector_integration();
let mut request = construct_payment_router_data();
request.request.payment_method_data = types::api::PaymentMethod::Card(types::api::CCard {
request.request.payment_method_data = types::api::PaymentMethod::Card(types::api::Card {
card_number: Secret::new("420000000000000000".to_string()),
card_exp_month: Secret::new("10".to_string()),
card_exp_year: Secret::new("2025".to_string()),

View File

@ -33,7 +33,7 @@ fn construct_payment_router_data() -> types::PaymentsAuthorizeRouterData {
request: types::PaymentsAuthorizeData {
amount: 100,
currency: enums::Currency::USD,
payment_method_data: types::api::PaymentMethod::Card(types::api::CCard {
payment_method_data: types::api::PaymentMethod::Card(types::api::Card {
card_number: Secret::new("5424000000000015".to_string()),
card_exp_month: Secret::new("10".to_string()),
card_exp_year: Secret::new("2025".to_string()),
@ -153,7 +153,7 @@ async fn payments_create_failure() {
> = connector.connector.get_connector_integration();
let mut request = construct_payment_router_data();
request.request.payment_method_data = types::api::PaymentMethod::Card(types::api::CCard {
request.request.payment_method_data = types::api::PaymentMethod::Card(types::api::Card {
card_number: Secret::new("542400000000001".to_string()),
card_exp_month: Secret::new("10".to_string()),
card_exp_year: Secret::new("2025".to_string()),

View File

@ -30,7 +30,7 @@ fn construct_payment_router_data() -> types::PaymentsAuthorizeRouterData {
request: types::PaymentsAuthorizeData {
amount: 100,
currency: enums::Currency::USD,
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_number: "4242424242424242".to_string().into(),
card_exp_month: "10".to_string().into(),
card_exp_year: "35".to_string().into(),

View File

@ -214,7 +214,7 @@ async fn should_fail_payment_for_incorrect_card_number() {
let response = Cybersource {}
.make_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_number: Secret::new("424242442424242".to_string()),
..utils::CCardType::default().0
}),
@ -234,7 +234,7 @@ async fn should_fail_payment_for_incorrect_exp_month() {
let response = Cybersource {}
.make_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_number: Secret::new("4242424242424242".to_string()),
card_exp_month: Secret::new("101".to_string()),
..utils::CCardType::default().0

View File

@ -43,7 +43,7 @@ async fn should_only_authorize_payment() {
let response = Fiserv {}
.authorize_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_number: Secret::new("4005550000000019".to_string()),
card_exp_month: Secret::new("02".to_string()),
card_exp_year: Secret::new("2035".to_string()),
@ -65,7 +65,7 @@ async fn should_authorize_and_capture_payment() {
let response = Fiserv {}
.make_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_number: Secret::new("4005550000000019".to_string()),
card_exp_month: Secret::new("02".to_string()),
card_exp_year: Secret::new("2035".to_string()),
@ -86,7 +86,7 @@ async fn should_capture_already_authorized_payment() {
let authorize_response = connector
.authorize_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_number: Secret::new("4005550000000019".to_string()),
card_exp_month: Secret::new("02".to_string()),
card_exp_year: Secret::new("2035".to_string()),
@ -119,7 +119,7 @@ async fn should_fail_payment_for_missing_cvc() {
let response = Fiserv {}
.make_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_number: Secret::new("4005550000000019".to_string()),
card_exp_month: Secret::new("02".to_string()),
card_exp_year: Secret::new("2035".to_string()),

View File

@ -129,7 +129,7 @@ async fn should_fail_payment_for_incorrect_cvc() {
let response = Globalpay {}
.make_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_number: Secret::new("4024007134364842".to_string()),
..utils::CCardType::default().0
}),

View File

@ -38,7 +38,7 @@ async fn should_only_authorize_payment() {
let response = Rapyd {}
.authorize_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_number: Secret::new("4111111111111111".to_string()),
card_exp_month: Secret::new("02".to_string()),
card_exp_year: Secret::new("2024".to_string()),
@ -60,7 +60,7 @@ async fn should_authorize_and_capture_payment() {
let response = Rapyd {}
.make_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_number: Secret::new("4111111111111111".to_string()),
card_exp_month: Secret::new("02".to_string()),
card_exp_year: Secret::new("2024".to_string()),
@ -137,7 +137,7 @@ async fn should_fail_payment_for_incorrect_card_number() {
let response = Rapyd {}
.make_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_number: Secret::new("0000000000000000".to_string()),
..utils::CCardType::default().0
}),

View File

@ -67,7 +67,7 @@ async fn should_fail_payment_for_incorrect_cvc() {
let response = Shift4 {}
.make_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_number: Secret::new("4024007134364842".to_string()),
..utils::CCardType::default().0
}),

View File

@ -35,7 +35,7 @@ impl utils::Connector for Stripe {
fn get_payment_authorize_data() -> Option<types::PaymentsAuthorizeData> {
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_number: Secret::new("4242424242424242".to_string()),
..utils::CCardType::default().0
}),
@ -132,7 +132,7 @@ async fn should_fail_payment_for_incorrect_card_number() {
let response = Stripe {}
.make_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_number: Secret::new("4024007134364842".to_string()),
..utils::CCardType::default().0
}),
@ -154,7 +154,7 @@ async fn should_fail_payment_for_no_card_number() {
let response = Stripe {}
.make_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_number: Secret::new("".to_string()),
..utils::CCardType::default().0
}),
@ -176,7 +176,7 @@ async fn should_fail_payment_for_invalid_exp_month() {
let response = Stripe {}
.make_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_exp_month: Secret::new("13".to_string()),
..utils::CCardType::default().0
}),
@ -195,7 +195,7 @@ async fn should_fail_payment_for_invalid_exp_year() {
let response = Stripe {}
.make_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_exp_year: Secret::new("2022".to_string()),
..utils::CCardType::default().0
}),
@ -214,7 +214,7 @@ async fn should_fail_payment_for_invalid_card_cvc() {
let response = Stripe {}
.make_payment(
Some(types::PaymentsAuthorizeData {
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
payment_method_data: types::api::PaymentMethod::Card(api::Card {
card_cvc: Secret::new("12".to_string()),
..utils::CCardType::default().0
}),

View File

@ -377,12 +377,12 @@ pub struct PaymentCaptureType(pub types::PaymentsCaptureData);
pub struct PaymentCancelType(pub types::PaymentsCancelData);
pub struct PaymentSyncType(pub types::PaymentsSyncData);
pub struct PaymentRefundType(pub types::RefundsData);
pub struct CCardType(pub api::CCard);
pub struct CCardType(pub api::Card);
pub struct BrowserInfoType(pub types::BrowserInformation);
impl Default for CCardType {
fn default() -> Self {
Self(api::CCard {
Self(api::Card {
card_number: Secret::new("4200000000000000".to_string()),
card_exp_month: Secret::new("10".to_string()),
card_exp_year: Secret::new("2025".to_string()),

View File

@ -64,7 +64,7 @@ impl WorldlineTest {
Some(types::PaymentsAuthorizeData {
amount: 3500,
currency: enums::Currency::USD,
payment_method_data: types::api::PaymentMethod::Card(types::api::CCard {
payment_method_data: types::api::PaymentMethod::Card(types::api::Card {
card_number: Secret::new(card_number.to_string()),
card_exp_month: Secret::new(card_exp_month.to_string()),
card_exp_year: Secret::new(card_exp_year.to_string()),

View File

@ -299,7 +299,7 @@ async fn payments_create_core() {
return_url: Some("http://example.com/payments".to_string()),
setup_future_usage: Some(api_enums::FutureUsage::OnSession),
authentication_type: Some(api_enums::AuthenticationType::NoThreeDs),
payment_method_data: Some(api::PaymentMethod::Card(api::CCard {
payment_method_data: Some(api::PaymentMethod::Card(api::Card {
card_number: "4242424242424242".to_string().into(),
card_exp_month: "10".to_string().into(),
card_exp_year: "35".to_string().into(),
@ -452,7 +452,7 @@ async fn payments_create_core_adyen_no_redirect() {
return_url: Some("http://example.com/payments".to_string()),
setup_future_usage: Some(api_enums::FutureUsage::OnSession),
authentication_type: Some(api_enums::AuthenticationType::NoThreeDs),
payment_method_data: Some(api::PaymentMethod::Card(api::CCard {
payment_method_data: Some(api::PaymentMethod::Card(api::Card {
card_number: "5555 3412 4444 1115".to_string().into(),
card_exp_month: "03".to_string().into(),
card_exp_year: "2030".to_string().into(),

View File

@ -59,7 +59,7 @@ async fn payments_create_core() {
return_url: Some("http://example.com/payments".to_string()),
setup_future_usage: None,
authentication_type: Some(api_enums::AuthenticationType::NoThreeDs),
payment_method_data: Some(api::PaymentMethod::Card(api::CCard {
payment_method_data: Some(api::PaymentMethod::Card(api::Card {
card_number: "4242424242424242".to_string().into(),
card_exp_month: "10".to_string().into(),
card_exp_year: "35".to_string().into(),
@ -209,7 +209,7 @@ async fn payments_create_core_adyen_no_redirect() {
return_url: Some("http://example.com/payments".to_string()),
setup_future_usage: Some(api_enums::FutureUsage::OffSession),
authentication_type: Some(api_enums::AuthenticationType::NoThreeDs),
payment_method_data: Some(api::PaymentMethod::Card(api::CCard {
payment_method_data: Some(api::PaymentMethod::Card(api::Card {
card_number: "5555 3412 4444 1115".to_string().into(),
card_exp_month: "03".to_string().into(),
card_exp_year: "2030".to_string().into(),

File diff suppressed because it is too large Load Diff