mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 17:47:54 +08:00
fix(router): Convert ephemeral to client secret auth list payment_method_customer (#1602)
Co-authored-by: Sahkal Poddar <sahkal.poddar@juspay.in> Co-authored-by: Abhishek Marrivagu <68317979+Abhicodes-crypto@users.noreply.github.com> Co-authored-by: Narayan Bhat <48803246+Narayanbhat166@users.noreply.github.com>
This commit is contained in:
@ -170,8 +170,8 @@ pub async fn list_customer_payment_method_api(
|
|||||||
path: web::Path<String>,
|
path: web::Path<String>,
|
||||||
json_payload: web::Query<payment_methods::PaymentMethodListRequest>,
|
json_payload: web::Query<payment_methods::PaymentMethodListRequest>,
|
||||||
) -> HttpResponse {
|
) -> HttpResponse {
|
||||||
let customer_id = path.into_inner();
|
|
||||||
let payload = json_payload.into_inner();
|
let payload = json_payload.into_inner();
|
||||||
|
let customer_id = path.into_inner();
|
||||||
let flow = Flow::CustomerPaymentMethodsList;
|
let flow = Flow::CustomerPaymentMethodsList;
|
||||||
|
|
||||||
wrap::compatibility_api_wrap::<
|
wrap::compatibility_api_wrap::<
|
||||||
@ -189,12 +189,12 @@ pub async fn list_customer_payment_method_api(
|
|||||||
&req,
|
&req,
|
||||||
payload,
|
payload,
|
||||||
|state, auth, req| {
|
|state, auth, req| {
|
||||||
cards::list_customer_payment_method(
|
cards::do_list_customer_pm_fetch_customer_if_not_passed(
|
||||||
state,
|
state,
|
||||||
auth.merchant_account,
|
auth.merchant_account,
|
||||||
auth.key_store,
|
auth.key_store,
|
||||||
req,
|
Some(req),
|
||||||
&customer_id,
|
Some(customer_id.as_str()),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
&auth::ApiKeyAuth,
|
&auth::ApiKeyAuth,
|
||||||
|
|||||||
@ -1499,15 +1499,47 @@ async fn filter_payment_mandate_based(
|
|||||||
Ok(recurring_filter)
|
Ok(recurring_filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn do_list_customer_pm_fetch_customer_if_not_passed(
|
||||||
|
state: &routes::AppState,
|
||||||
|
merchant_account: domain::MerchantAccount,
|
||||||
|
key_store: domain::MerchantKeyStore,
|
||||||
|
req: Option<api::PaymentMethodListRequest>,
|
||||||
|
customer_id: Option<&str>,
|
||||||
|
) -> errors::RouterResponse<api::CustomerPaymentMethodsListResponse> {
|
||||||
|
let db = &*state.store;
|
||||||
|
if let Some(customer_id) = customer_id {
|
||||||
|
list_customer_payment_method(state, merchant_account, key_store, None, customer_id).await
|
||||||
|
} else {
|
||||||
|
let cloned_secret = req.and_then(|r| r.client_secret.as_ref().cloned());
|
||||||
|
let payment_intent = helpers::verify_payment_intent_time_and_client_secret(
|
||||||
|
db,
|
||||||
|
&merchant_account,
|
||||||
|
cloned_secret,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let customer_id = payment_intent
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|intent| intent.customer_id.to_owned())
|
||||||
|
.ok_or(errors::ApiErrorResponse::CustomerNotFound)?;
|
||||||
|
list_customer_payment_method(
|
||||||
|
state,
|
||||||
|
merchant_account,
|
||||||
|
key_store,
|
||||||
|
payment_intent,
|
||||||
|
&customer_id,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn list_customer_payment_method(
|
pub async fn list_customer_payment_method(
|
||||||
state: &routes::AppState,
|
state: &routes::AppState,
|
||||||
merchant_account: domain::MerchantAccount,
|
merchant_account: domain::MerchantAccount,
|
||||||
key_store: domain::MerchantKeyStore,
|
key_store: domain::MerchantKeyStore,
|
||||||
req: api::PaymentMethodListRequest,
|
payment_intent: Option<storage::PaymentIntent>,
|
||||||
customer_id: &str,
|
customer_id: &str,
|
||||||
) -> errors::RouterResponse<api::CustomerPaymentMethodsListResponse> {
|
) -> errors::RouterResponse<api::CustomerPaymentMethodsListResponse> {
|
||||||
let db = &*state.store;
|
let db = &*state.store;
|
||||||
|
|
||||||
db.find_customer_by_customer_id_merchant_id(
|
db.find_customer_by_customer_id_merchant_id(
|
||||||
customer_id,
|
customer_id,
|
||||||
&merchant_account.merchant_id,
|
&merchant_account.merchant_id,
|
||||||
@ -1556,15 +1588,10 @@ pub async fn list_customer_payment_method(
|
|||||||
parent_payment_method_token, pma.payment_method
|
parent_payment_method_token, pma.payment_method
|
||||||
);
|
);
|
||||||
|
|
||||||
let payment_intent = helpers::verify_payment_intent_time_and_client_secret(
|
|
||||||
db,
|
|
||||||
&merchant_account,
|
|
||||||
req.client_secret.clone(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
let current_datetime_utc = common_utils::date_time::now();
|
let current_datetime_utc = common_utils::date_time::now();
|
||||||
let time_eslapsed = current_datetime_utc
|
let time_eslapsed = current_datetime_utc
|
||||||
- payment_intent
|
- payment_intent
|
||||||
|
.as_ref()
|
||||||
.map(|intent| intent.created_at)
|
.map(|intent| intent.created_at)
|
||||||
.unwrap_or_else(|| current_datetime_utc);
|
.unwrap_or_else(|| current_datetime_utc);
|
||||||
redis_conn
|
redis_conn
|
||||||
|
|||||||
@ -90,6 +90,7 @@ Never share your secret api keys. Keep them guarded and secure.
|
|||||||
crate::routes::payment_methods::create_payment_method_api,
|
crate::routes::payment_methods::create_payment_method_api,
|
||||||
crate::routes::payment_methods::list_payment_method_api,
|
crate::routes::payment_methods::list_payment_method_api,
|
||||||
crate::routes::payment_methods::list_customer_payment_method_api,
|
crate::routes::payment_methods::list_customer_payment_method_api,
|
||||||
|
crate::routes::payment_methods::list_customer_payment_method_api_client,
|
||||||
crate::routes::payment_methods::payment_method_retrieve_api,
|
crate::routes::payment_methods::payment_method_retrieve_api,
|
||||||
crate::routes::payment_methods::payment_method_update_api,
|
crate::routes::payment_methods::payment_method_update_api,
|
||||||
crate::routes::payment_methods::payment_method_delete_api,
|
crate::routes::payment_methods::payment_method_delete_api,
|
||||||
|
|||||||
@ -222,14 +222,18 @@ impl Customers {
|
|||||||
route = route
|
route = route
|
||||||
.service(web::resource("").route(web::post().to(customers_create)))
|
.service(web::resource("").route(web::post().to(customers_create)))
|
||||||
.service(
|
.service(
|
||||||
web::resource("/{customer_id}")
|
web::resource("/payment_methods")
|
||||||
.route(web::get().to(customers_retrieve))
|
.route(web::get().to(list_customer_payment_method_api_client)),
|
||||||
.route(web::post().to(customers_update))
|
|
||||||
.route(web::delete().to(customers_delete)),
|
|
||||||
)
|
)
|
||||||
.service(
|
.service(
|
||||||
web::resource("/{customer_id}/payment_methods")
|
web::resource("/{customer_id}/payment_methods")
|
||||||
.route(web::get().to(list_customer_payment_method_api)),
|
.route(web::get().to(list_customer_payment_method_api)),
|
||||||
|
)
|
||||||
|
.service(
|
||||||
|
web::resource("/{customer_id}")
|
||||||
|
.route(web::get().to(customers_retrieve))
|
||||||
|
.route(web::post().to(customers_update))
|
||||||
|
.route(web::delete().to(customers_delete)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
route
|
route
|
||||||
|
|||||||
@ -98,7 +98,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 = "/customer/{customer_id}/payment_methods",
|
path = "/customers/{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"),
|
||||||
@ -115,39 +115,93 @@ pub async fn list_payment_method_api(
|
|||||||
),
|
),
|
||||||
tag = "Payment Methods",
|
tag = "Payment Methods",
|
||||||
operation_id = "List all Payment Methods for a Customer",
|
operation_id = "List all Payment Methods for a Customer",
|
||||||
security(("api_key" = []), ("ephemeral_key" = []))
|
security(("api_key" = []))
|
||||||
)]
|
)]
|
||||||
#[instrument(skip_all, fields(flow = ?Flow::CustomerPaymentMethodsList))]
|
#[instrument(skip_all, fields(flow = ?Flow::CustomerPaymentMethodsList))]
|
||||||
pub async fn list_customer_payment_method_api(
|
pub async fn list_customer_payment_method_api(
|
||||||
state: web::Data<AppState>,
|
state: web::Data<AppState>,
|
||||||
customer_id: web::Path<(String,)>,
|
customer_id: web::Path<(String,)>,
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
json_payload: web::Query<payment_methods::PaymentMethodListRequest>,
|
query_payload: web::Query<payment_methods::PaymentMethodListRequest>,
|
||||||
) -> HttpResponse {
|
) -> HttpResponse {
|
||||||
let flow = Flow::CustomerPaymentMethodsList;
|
let flow = Flow::CustomerPaymentMethodsList;
|
||||||
let customer_id = customer_id.into_inner().0;
|
let payload = query_payload.into_inner();
|
||||||
|
let (auth, _) = match auth::check_client_secret_and_get_auth(req.headers(), &payload) {
|
||||||
let auth_type = match auth::is_ephemeral_auth(req.headers(), &*state.store, &customer_id).await
|
Ok((auth, _auth_flow)) => (auth, _auth_flow),
|
||||||
{
|
Err(e) => return api::log_and_return_error_response(e),
|
||||||
Ok(auth_type) => auth_type,
|
|
||||||
Err(err) => return api::log_and_return_error_response(err),
|
|
||||||
};
|
};
|
||||||
|
let customer_id = customer_id.into_inner().0;
|
||||||
api::server_wrap(
|
api::server_wrap(
|
||||||
flow,
|
flow,
|
||||||
state.get_ref(),
|
state.get_ref(),
|
||||||
&req,
|
&req,
|
||||||
json_payload.into_inner(),
|
payload,
|
||||||
|state, auth, req| {
|
|state, auth, req| {
|
||||||
cards::list_customer_payment_method(
|
cards::do_list_customer_pm_fetch_customer_if_not_passed(
|
||||||
state,
|
state,
|
||||||
auth.merchant_account,
|
auth.merchant_account,
|
||||||
auth.key_store,
|
auth.key_store,
|
||||||
req,
|
Some(req),
|
||||||
&customer_id,
|
Some(&customer_id),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
&*auth_type,
|
&*auth,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// List payment methods for a Customer
|
||||||
|
///
|
||||||
|
/// To filter and list the applicable payment methods for a particular Customer ID
|
||||||
|
#[utoipa::path(
|
||||||
|
get,
|
||||||
|
path = "/customers/payment_methods",
|
||||||
|
params (
|
||||||
|
("client-secret" = String, Path, description = "A secret known only to your application and the authorization server"),
|
||||||
|
("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 for customer tied to its respective client-secret passed in the param", body = CustomerPaymentMethodsListResponse),
|
||||||
|
(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",
|
||||||
|
security(("publishable_key" = []))
|
||||||
|
)]
|
||||||
|
#[instrument(skip_all, fields(flow = ?Flow::CustomerPaymentMethodsList))]
|
||||||
|
pub async fn list_customer_payment_method_api_client(
|
||||||
|
state: web::Data<AppState>,
|
||||||
|
req: HttpRequest,
|
||||||
|
query_payload: web::Query<payment_methods::PaymentMethodListRequest>,
|
||||||
|
) -> HttpResponse {
|
||||||
|
let flow = Flow::CustomerPaymentMethodsList;
|
||||||
|
let payload = query_payload.into_inner();
|
||||||
|
let (auth, _) = match auth::check_client_secret_and_get_auth(req.headers(), &payload) {
|
||||||
|
Ok((auth, _auth_flow)) => (auth, _auth_flow),
|
||||||
|
Err(e) => return api::log_and_return_error_response(e),
|
||||||
|
};
|
||||||
|
api::server_wrap(
|
||||||
|
flow,
|
||||||
|
state.get_ref(),
|
||||||
|
&req,
|
||||||
|
payload,
|
||||||
|
|state, auth, req| {
|
||||||
|
cards::do_list_customer_pm_fetch_customer_if_not_passed(
|
||||||
|
state,
|
||||||
|
auth.merchant_account,
|
||||||
|
auth.key_store,
|
||||||
|
Some(req),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
&*auth,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
@ -422,7 +422,6 @@ where
|
|||||||
}
|
}
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((Box::new(ApiKeyAuth), api::AuthFlow::Merchant))
|
Ok((Box::new(ApiKeyAuth), api::AuthFlow::Merchant))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -129,7 +129,47 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/customer/{customer_id}/payment_methods": {
|
"/customers": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Customers"
|
||||||
|
],
|
||||||
|
"summary": "Create Customer",
|
||||||
|
"description": "Create Customer\n\nCreate 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.",
|
||||||
|
"operationId": "Create a Customer",
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/CustomerRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Customer Created",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/CustomerResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid data"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"api_key": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/customers/payment_methods": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"Payment Methods"
|
"Payment Methods"
|
||||||
@ -138,6 +178,15 @@
|
|||||||
"description": "List payment methods for a Customer\n\nTo filter and list the applicable payment methods for a particular Customer ID",
|
"description": "List payment methods for a Customer\n\nTo filter and list the applicable payment methods for a particular Customer ID",
|
||||||
"operationId": "List all Payment Methods for a Customer",
|
"operationId": "List all Payment Methods for a Customer",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "client-secret",
|
||||||
|
"in": "path",
|
||||||
|
"description": "A secret known only to your application and the authorization server",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "customer_id",
|
"name": "customer_id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
@ -212,7 +261,7 @@
|
|||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Payment Methods retrieved",
|
"description": "Payment Methods retrieved for customer tied to its respective client-secret passed in the param",
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
@ -230,50 +279,7 @@
|
|||||||
},
|
},
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
"api_key": []
|
"publishable_key": []
|
||||||
},
|
|
||||||
{
|
|
||||||
"ephemeral_key": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/customers": {
|
|
||||||
"post": {
|
|
||||||
"tags": [
|
|
||||||
"Customers"
|
|
||||||
],
|
|
||||||
"summary": "Create Customer",
|
|
||||||
"description": "Create Customer\n\nCreate 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.",
|
|
||||||
"operationId": "Create a Customer",
|
|
||||||
"requestBody": {
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/CustomerRequest"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "Customer Created",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/CustomerResponse"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"400": {
|
|
||||||
"description": "Invalid data"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"api_key": []
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -410,6 +416,112 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/customers/{customer_id}/payment_methods": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Payment Methods"
|
||||||
|
],
|
||||||
|
"summary": "List payment methods for a Customer",
|
||||||
|
"description": "List payment methods for a Customer\n\nTo filter and list the applicable payment methods for a particular Customer ID",
|
||||||
|
"operationId": "List all Payment Methods for a Customer",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "customer_id",
|
||||||
|
"in": "path",
|
||||||
|
"description": "The unique identifier for the customer account",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "accepted_country",
|
||||||
|
"in": "query",
|
||||||
|
"description": "The two-letter ISO currency code",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "accepted_currency",
|
||||||
|
"in": "path",
|
||||||
|
"description": "The three-letter ISO currency code",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/Currency"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "minimum_amount",
|
||||||
|
"in": "query",
|
||||||
|
"description": "The minimum amount accepted for processing by the particular payment method.",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "maximum_amount",
|
||||||
|
"in": "query",
|
||||||
|
"description": "The maximum amount amount accepted for processing by the particular payment method.",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "recurring_payment_enabled",
|
||||||
|
"in": "query",
|
||||||
|
"description": "Indicates whether the payment method is eligible for recurring payments",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "installment_payment_enabled",
|
||||||
|
"in": "query",
|
||||||
|
"description": "Indicates whether the payment method is eligible for installment payments",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Payment Methods retrieved",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/CustomerPaymentMethodsListResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid Data"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Payment Methods does not exist in records"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"api_key": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/disputes/list": {
|
"/disputes/list": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
|
|||||||
Reference in New Issue
Block a user