Remove pay_u module

This commit is contained in:
Adrian Woźniak 2022-05-04 07:40:34 +02:00
parent b4dc801820
commit 383b14b86a
No known key found for this signature in database
GPG Key ID: 0012845A89C7352B
15 changed files with 0 additions and 2609 deletions

View File

@ -1,77 +0,0 @@
//! This module allow to create credit request during create order request
use serde::{Deserialize, Serialize};
use crate::{Address, ShoppingCart};
/// Describe customer during credit request
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Applicant {
/// Applicants email address
/// Recommended
#[serde(skip_serializing_if = "Option::is_none")]
email: Option<String>,
/// Applicants phone number
/// Recommended
#[serde(skip_serializing_if = "Option::is_none")]
phone: Option<String>,
/// Applicants first name
/// Recommended
#[serde(skip_serializing_if = "Option::is_none")]
first_name: Option<String>,
/// Applicants last name
/// Recommended
#[serde(skip_serializing_if = "Option::is_none")]
last_name: Option<String>,
/// Language code, ISO-639-1 compliant. Denotes the language version of
/// PayU hosted payment page and of e-mail messages sent from PayU to the
/// payer (supported values are here).
/// Recommended
#[serde(skip_serializing_if = "Option::is_none")]
language: Option<String>,
/// National Identification Number
/// Recommended
#[serde(skip_serializing_if = "Option::is_none")]
nin: Option<String>,
/// Section containing data about applicants address.
/// Recommended
#[serde(skip_serializing_if = "Option::is_none")]
address: Option<Address>,
/// Additional information about person applying for credit.
/// Recommended
#[serde(skip_serializing_if = "Option::is_none")]
additional_info: Option<ApplicantAdditionalInfo>,
}
/// Allow to create credit request
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct Credit {
/// Section containing data of the ordered products
#[serde(skip_serializing_if = "Option::is_none")]
shopping_carts: Option<Vec<ShoppingCart>>,
/// Section containing data of person applying for a credit
#[serde(skip_serializing_if = "Option::is_none")]
applicant: Option<Applicant>,
}
impl Credit {
pub fn with_shopping_carts<ShoppingCarts>(mut self, shopping_carts: ShoppingCarts) -> Self
where
ShoppingCarts: Iterator<Item = ShoppingCart>,
{
self.shopping_carts = Some(shopping_carts.collect());
self
}
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ApplicantAdditionalInfo {
/// Information whether there were previous, successfully completed orders
/// for applicant.
/// Recommended
#[serde(skip_serializing_if = "Option::is_none")]
has_successfully_finished_order_in_shop: Option<String>,
}

View File

@ -1,162 +0,0 @@
use std::fmt;
use serde::de::{self, Error, Visitor};
pub(crate) fn deserialize_i32<'de, D>(d: D) -> std::result::Result<i32, D::Error>
where
D: serde::Deserializer<'de>,
{
d.deserialize_string(I32Visitor)
}
pub(crate) fn deserialize_i32_newtype<'de, N: From<i32>, D>(
d: D,
) -> std::result::Result<N, D::Error>
where
D: serde::Deserializer<'de>,
{
d.deserialize_string(I32Visitor).map(N::from)
}
pub(crate) fn deserialize_u32<'de, D>(d: D) -> std::result::Result<u32, D::Error>
where
D: serde::Deserializer<'de>,
{
d.deserialize_string(U32Visitor)
}
struct I32Visitor;
impl<'de> Visitor<'de> for I32Visitor {
type Value = i32;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an integer between -2^31 and 2^31")
}
fn visit_i8<E>(self, value: i8) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(i32::from(value))
}
fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(value)
}
fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
where
E: de::Error,
{
use std::i32;
if value >= i64::from(i32::MIN) && value <= i64::from(i32::MAX) {
Ok(value as i32)
} else {
Err(E::custom(format!("i32 out of range: {}", value)))
}
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
if let Ok(value) = v.parse::<i32>() {
Ok(value)
} else {
Err(E::custom(format!("str does not contains valid i32: {}", v)))
}
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: Error,
{
if let Ok(value) = v.parse::<i32>() {
Ok(value)
} else {
Err(E::custom(format!(
"string does not contains valid i32: {}",
v
)))
}
}
// Similar for other methods:
// - visit_i16
// - visit_u8
// - visit_u16
// - visit_u32
// - visit_u64
}
struct U32Visitor;
impl<'de> Visitor<'de> for U32Visitor {
type Value = u32;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an integer between -2^31 and 2^31")
}
fn visit_u8<E>(self, value: u8) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(u32::from(value))
}
fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(value)
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
use std::u32;
if value >= u64::from(u32::MIN) && value <= u64::from(u32::MAX) {
Ok(value as u32)
} else {
Err(E::custom(format!("i32 out of range: {}", value)))
}
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
if let Ok(value) = v.parse::<u32>() {
Ok(value)
} else {
Err(E::custom(format!("str does not contains valid i32: {}", v)))
}
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: Error,
{
if let Ok(value) = v.parse::<u32>() {
Ok(value)
} else {
Err(E::custom(format!(
"string does not contains valid i32: {}",
v
)))
}
}
// Similar for other methods:
// - visit_i16
// - visit_u8
// - visit_u16
// - visit_u32
// - visit_u64
}

File diff suppressed because it is too large Load Diff

View File

@ -1,161 +0,0 @@
//! Notification objects. Those objects will be send on notify_url if was given.
//!
//! To enable notifications for a specific payment, specify the notifyUrl
//! parameter in the payment form. Each payment can receive a different URL to
//! which notifications will be sent.
//!
//! Every notification is sent asynchronously. After your system receives a
//! notification with the status COMPLETED, instruct it to ignore any further
//! notifications.
//!
//! After sending a notification, PayU system requires a 200 HTTP status code in
//! response. If it receives a different status code, it will resend the
//! notification. Your system should also take account of situations where a
//! notification is sent several times with the same status. For each repeated
//! notification, response with code 200 should be sent as well.
//!
//! To ensure trusted communication between PayU and your shop, you must verify
//! the signature value available in the OpenPayu-Signature header each time
//! your system receives any notification from a PayU server. Refer to the
//! Verification of notifications signature for more information.
//!
//! Notifications are sent for orders in the following statuses: PENDING,
//! WAITING_FOR_CONFIRMATION, COMPLETED, CANCELED.
//!
//! Note: if you filter IP addresses, remember to allow IPs used by PayU to send
//! the notifications. These are:
//!
//! ### PRODUCTION
//!
//! > 185.68.12.10, 185.68.12.11, 185.68.12.12, 185.68.12.26, 185.68.12.27,
//! > 185.68.12.28
//!
//! ### SANDBOX
//!
//! > 185.68.14.10, 185.68.14.11, 185.68.14.12, 185.68.14.26, 185.68.14.27,
//! > 185.68.14.28
//!
//! ## Payment lifecycle
//!
//! You can configure a separate auto-receive / automatic collection parameter
//! for each payment method via the Management Panel.
//!
//! By default, auto-receive is enabled. The basic payment sequence is as
//! follows:
//!
//! 1) Each successfully authorized payment for an order is captured.
//! 2) The buyer is charged with the order amount.
//! 3) The shop balance is increased by the order amount.
//! 4) PayU calculates its commission to the order.
//!
//! If the auto-receive is turned off, you should capture each order using a PUT
//! method (Order capture) or cancel using DELETE method (Cancellation).
//!
//! If no such action is taken the order is auto-canceled. Automatic
//! cancellation occurs after a number of days indicated for the payment method.
//!
//! <img src="https://developers.payu.com/images/order_statusesV2-en.png" />
use serde::Deserialize;
use super::deserialize;
use crate::OrderId;
/// Payment notification object received on notify_url
///
/// See [crate::req::CreateOrder::notify_url]
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct StatusUpdate {
/// Section containing order object
pub order: Order,
/// Moment of accepting the transaction and adding funds from the
/// transaction to the Shop balance. Format: "%Y-%M-%DT%h:%m:%s%z."
/// Example: "2020-06-09T17:52:04.644+02:00". If the millisecond counter
/// is "000" then milliseconds are not sent and the format changes to:
/// "%Y-%M-%DT%h:%m:%s". Is present only for the status "COMPLETED".
pub local_receipt_date_time: Option<String>,
/// Array of objects related to transaction identification. In case of
/// statuses:
/// * `"WAITING_FOR_CONFIRMATION"` and `"COMPLETED"` - Contains one element
/// with two parameters: name and value,
/// * `"PENDING"` - may contain object with aforementioned parameters or it
/// can be empty.
///
/// Also properties `name`
///
/// Static value. The payment identifier, displayed on transaction
/// statements as "Trans ID" and within the transaction search option in
/// the Management Panel.
///
/// Also properties `value`
///
/// Transaction ID in PayU system (data type - string).
pub properties: Option<Vec<super::Prop>>,
}
impl StatusUpdate {
pub fn status(&self) -> super::PaymentStatus {
self.order.status
}
/// See [crate::req::OrderCreate::ext_order_id]
pub fn ext_order_id(&self) -> &str {
self.order.ext_order_id.as_deref().unwrap_or_default()
}
pub fn has_ext_order_id(&self) -> bool {
self.order.ext_order_id.is_some()
}
}
/// Refund notification object
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RefundUpdate {
pub ext_order_id: String,
pub order_id: OrderId,
pub refund: Refund,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Refund {
pub refund_id: String,
pub amount: String,
pub currency_code: String,
pub status: super::RefundStatus,
pub status_date_time: String,
pub reason: String,
pub reason_description: String,
pub refund_date: String,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Order {
pub notify_url: Option<String>,
/// Customer client IP address
pub customer_ip: String,
/// Secret pos ip. This is connected to PayU account
#[serde(deserialize_with = "deserialize::deserialize_i32_newtype")]
pub merchant_pos_id: super::MerchantPosId,
/// Transaction description
pub description: String,
/// 3 characters currency identifier, ex. PLN
pub currency_code: String,
/// Total price of the order in pennies (e.g. 1000 is 10.00 EUR).
/// Applies also to currencies without subunits (e.g. 1000 is 10
/// HUF).
#[serde(deserialize_with = "deserialize::deserialize_i32")]
pub total_amount: super::Price,
/// @see [crate::Buyer]
pub buyer: Option<super::Buyer>,
/// List of products
pub products: Vec<super::Product>,
#[serde(skip_serializing)]
pub order_create_date: Option<String>,
pub pay_method: Option<super::PayMethod>,
pub status: super::PaymentStatus,
pub ext_order_id: Option<String>,
}

View File

@ -1,381 +0,0 @@
//! Objects used to send requests to PayU
use serde::{Deserialize, Serialize};
use crate::credit::Credit;
#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Refund {
pub(crate) description: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) amount: Option<super::Price>,
}
impl Refund {
pub fn new<Description>(description: Description, amount: Option<super::Price>) -> Self
where
Description: Into<String>,
{
Self {
description: description.into(),
amount,
}
}
pub fn description(&self) -> &str {
&self.description
}
pub fn amount(&self) -> Option<super::Price> {
self.amount
}
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct OrderCreate {
/// ID of an order used in merchant system. Order identifier assigned by
/// the merchant. It enables merchants to find a specific order
/// in their system. This value must be unique within a single
/// POS.
pub(crate) ext_order_id: Option<String>,
/// URL to which web hook will be send. It's important to return 200 to
/// all notifications.
///
/// All notifications are send as POST with JSON payload
///
/// Notifications are sent immediately after a payment status changes.
/// If the notification is not received by the Shop application,
/// it will be sent again in accordance with the table below:
///
/// | Attempt | Time |
/// |---------|------|
/// | 1 | immediately |
/// | 2 | 1 minute |
/// | 3 | 2 minutes |
/// | 4 | 5 minutes |
/// | 5 | 10 minutes |
/// | 6 | 30 minutes |
/// | 7 | 1 hour |
/// | 8 | 2 hours |
/// | 9 | 3 hours |
/// | 10| 6 hours |
/// | 11| 9 hours |
/// | 12| 12 hours |
/// | 13| 15 hours |
/// | 14| 18 hours |
/// | 15| 21 hours |
/// | 16| 24 hours |
/// | 17| 36 hours |
/// | 18| 48 hours |
/// | 19| 60 hours |
/// | 20| 72 hours |
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) notify_url: Option<String>,
/// Address for redirecting the customer after payment is commenced. If
/// the payment has not been authorized, error=501 parameter
/// will be added. Please note that no decision regarding
/// payment status should be made depending on the presence or
/// lack of this parameter (to get payment status, wait for
/// notification or retrieve order details).
///
/// IMPORTANT: the address must be compliant with the structure below:
/// <img src="https://developers.payu.com/images/continueUrlStructure_en.png" />
///
/// Please keep in mind:
/// * accepted schemas are http and https,
/// * such elements as port, path, query and fragment are optional,
/// * query values must be encoded.
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) continue_url: Option<String>,
/// Payers IP address, e.g. 123.123.123.123. Note: 0.0.0.0 is not
/// accepted.
pub(crate) customer_ip: String,
/// Secret pos ip. This is connected to PayU account
#[serde(
serialize_with = "crate::serialize::serialize_newtype",
deserialize_with = "crate::deserialize::deserialize_i32_newtype"
)]
pub(crate) merchant_pos_id: super::MerchantPosId,
/// Transaction description
pub(crate) description: String,
/// 3 characters currency identifier, ex. PLN
pub(crate) currency_code: String,
/// Total price of the order in pennies (e.g. 1000 is 10.00 EUR).
/// Applies also to currencies without subunits (e.g. 1000 is 10
/// HUF).
#[serde(
serialize_with = "crate::serialize::serialize_i32",
deserialize_with = "crate::deserialize::deserialize_i32"
)]
pub(crate) total_amount: super::Price,
/// @see [crate::Buyer]
pub(crate) buyer: Option<super::Buyer>,
/// List of products
pub(crate) products: Vec<super::Product>,
#[serde(skip_serializing)]
pub(crate) order_create_date: Option<String>,
/// Duration for the validity of an order (in seconds), during which
/// time payment must be made. Default value 86400.
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) validity_time: Option<u16>,
/// Additional description of the order.
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) additional_description: Option<String>,
/// Text visible on the PayU payment page (max. 80 chars).
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) visible_description: Option<String>,
/// Payment recipient name followed by payment description (order ID,
/// ticket number etc) visible on card statement (max. 22
/// chars). The name should be easy to recognize by the
/// cardholder (e.g "shop.com 124343"). If field
/// is not provided, static name configured by PayU will be used.
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) statement_description: Option<String>,
#[serde(flatten, skip_serializing_if = "Option::is_none")]
pub(crate) muct: Option<super::muct::MultiUseCartToken>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) credit: Option<Credit>,
}
impl OrderCreate {
pub fn build<CustomerIp, Currency, Description>(
buyer: super::Buyer,
customer_ip: CustomerIp,
currency: Currency,
description: Description,
) -> super::Result<Self>
where
CustomerIp: Into<String>,
Currency: Into<String>,
Description: Into<String>,
{
let customer_ip = customer_ip.into();
if &customer_ip == "0.0.0.0" {
return Err(super::Error::CustomerIp);
}
Ok(Self {
ext_order_id: None,
notify_url: None,
continue_url: None,
customer_ip,
merchant_pos_id: 0.into(),
description: description.into(),
currency_code: currency.into(),
total_amount: 0,
buyer: Some(buyer),
products: Vec::new(),
order_create_date: None,
validity_time: None,
additional_description: None,
visible_description: None,
statement_description: None,
muct: None,
credit: None,
})
}
/// ID of an order used in merchant system. Order identifier assigned by
/// the merchant. It enables merchants to find a specific order
/// in their system. This value must be unique within a single
/// POS.
pub fn with_ext_order_id<S: Into<String>>(mut self, ext_order_id: S) -> Self {
self.ext_order_id = Some(ext_order_id.into());
self
}
/// Duration for the validity of an order (in seconds), during which
/// time payment must be made. Default value 86400.
pub fn with_validity_time(mut self, validity_time: u16) -> Self {
self.validity_time = Some(validity_time);
self
}
pub fn with_multi_use_token(
mut self,
recurring: super::muct::Recurring,
card_on_file: super::muct::CardOnFile,
) -> Self {
self.muct = Some(super::muct::MultiUseCartToken {
recurring,
card_on_file,
});
self
}
pub fn with_products<Products>(mut self, products: Products) -> Self
where
Products: Iterator<Item = super::Product>,
{
self.products.extend(products);
self.total_amount = self
.products
.iter()
.fold(0, |agg, p| agg + (p.quantity as i32 * p.unit_price as i32));
self
}
pub fn with_product(mut self, product: super::Product) -> Self {
self.products.push(product);
self.total_amount = self
.products
.iter()
.fold(0, |agg, p| agg + (p.quantity as i32 * p.unit_price as i32));
self
}
/// Description of the an order.
///
/// > This method will override initial description!
pub fn with_description<Description>(mut self, desc: Description) -> Self
where
Description: Into<String>,
{
self.description = String::from(desc.into().trim());
self
}
/// Additional description of the order.
pub fn with_additional_description<S: Into<String>>(
mut self,
additional_description: S,
) -> Self {
self.additional_description = Some(additional_description.into());
self
}
/// Text visible on the PayU payment page (max. 80 chars).
pub fn with_visible_description(mut self, visible_description: &str) -> Self {
let visible_description = if visible_description.len() > 60 {
&visible_description[..60]
} else {
visible_description
};
self.visible_description = Some(String::from(visible_description));
self
}
/// Payment recipient name followed by payment description (order ID,
/// ticket number etc) visible on card statement (max. 22
/// chars). The name should be easy to recognize by the
/// cardholder (e.g "shop.com 124343"). If field
/// is not provided, static name configured by PayU will be used.
pub fn with_statement_description<Description>(mut self, desc: Description) -> Self
where
Description: Into<String>,
{
self.statement_description = Some(String::from(desc.into().trim()));
self
}
/// Add url to which PayU will be able to send http request with payment
/// status updates
///
/// All requests from PayU should receive 200 response!
///
/// See more [crate::res::Order::notify_url]
pub fn with_notify_url<NotifyUrl>(mut self, notify_url: NotifyUrl) -> Self
where
NotifyUrl: Into<String>,
{
self.notify_url = Some(notify_url.into());
self
}
/// Address for redirecting the customer after payment is commenced. If
/// the payment has not been authorized, error=501 parameter
/// will be added. Please note that no decision regarding
/// payment status should be made depending on the presence or
/// lack of this parameter (to get payment status, wait for
/// notification or retrieve order details).
pub fn with_continue_url<ContinueUrl>(mut self, continue_url: ContinueUrl) -> Self
where
ContinueUrl: Into<String>,
{
self.continue_url = Some(continue_url.into());
self
}
/// Section containing credit data. This information is not required,
/// but it is strongly recommended to include it. Otherwise the
/// buyer will be prompted to provide missing data on provider
/// page when payment by Installments or Pay later.
pub fn with_credit(mut self, credit: Credit) -> Self {
self.credit = Some(credit);
self
}
/// URL to which web hook will be send. It's important to return 200 to
/// all notifications.
///
/// All notifications are send as POST with JSON payload
///
/// Notifications are sent immediately after a payment status changes.
/// If the notification is not received by the Shop application,
/// it will be sent again in accordance with the table below:
///
/// | Attempt | Time |
/// |---------|------|
/// | 1 | immediately |
/// | 2 | 1 minute |
/// | 3 | 2 minutes |
/// | 4 | 5 minutes |
/// | 5 | 10 minutes |
/// | 6 | 30 minutes |
/// | 7 | 1 hour |
/// | 8 | 2 hours |
/// | 9 | 3 hours |
/// | 10| 6 hours |
/// | 11| 9 hours |
/// | 12| 12 hours |
/// | 13| 15 hours |
/// | 14| 18 hours |
/// | 15| 21 hours |
/// | 16| 24 hours |
/// | 17| 36 hours |
/// | 18| 48 hours |
/// | 19| 60 hours |
/// | 20| 72 hours |
pub fn notify_url(&self) -> &Option<String> {
&self.notify_url
}
/// Customer IP address from http request received from client
pub fn customer_ip(&self) -> &String {
&self.customer_ip
}
pub fn merchant_pos_id(&self) -> super::MerchantPosId {
self.merchant_pos_id
}
pub fn description(&self) -> &String {
&self.description
}
pub fn currency_code(&self) -> &String {
&self.currency_code
}
pub fn total_amount(&self) -> &super::Price {
&self.total_amount
}
pub fn buyer(&self) -> &Option<super::Buyer> {
&self.buyer
}
pub fn products(&self) -> &[super::Product] {
&self.products
}
pub fn order_create_date(&self) -> &Option<String> {
&self.order_create_date
}
pub(crate) fn with_merchant_pos_id(mut self, merchant_pos_id: super::MerchantPosId) -> Self {
self.merchant_pos_id = merchant_pos_id;
self
}
}

View File

@ -1,144 +0,0 @@
use crate::{OrderId, Refund, Status};
#[derive(serde::Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct CreateOrder {
/// Http status as a text
pub status: Status,
/// Client should be redirected to this URI
pub redirect_uri: String,
/// This should be connected to your own order
pub order_id: OrderId,
/// This is YOUR_EXT_ORDER_ID
pub ext_order_id: Option<String>,
}
#[derive(serde::Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RefundDetails {
pub order_id: Option<String>,
pub refund: Option<Refund>,
pub status: Status,
}
#[derive(serde::Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Refunds {
pub refunds: Vec<Refund>,
}
#[derive(serde::Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TransactionPayMethod {
pub value: String,
}
#[derive(serde::Deserialize, Debug)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum CardProfile {
Consumer,
Business,
}
#[derive(serde::Deserialize, Debug)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum CardClassification {
Debit,
Credit,
}
#[derive(serde::Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TransactionCartData {
/// // "543402******4014",
pub card_number_masked: String,
/// MC (MasterCard/Maestro), VS (Visa)
/// Example; "MC"
pub card_scheme: String,
pub card_profile: CardProfile,
pub card_classification: CardClassification,
/// Example: "000"
pub card_response_code: String,
/// Example: "000 - OK"
pub card_response_code_desc: String,
/// Example: "5"
pub card_eci_code: String,
/// Example: "AY",
pub card3ds_status: String,
/// Example: "PL",
pub card_bin_country: String,
/// Example: "MCC0111LL1121"
pub first_transaction_id: String,
}
/// > Installment proposal on the Sandbox environment is not related to the
/// > order amount and always returns data for 480 PLN.
#[derive(serde::Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TransactionCardInstallmentProposal {
/// Example: "5aff3ba8-0c37-4da1-ba4a-4ff24bcc2eed"
pub proposal_id: String,
}
#[derive(serde::Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TransactionCart {
pub cart_data: TransactionCartData,
pub card_installment_proposal: TransactionCardInstallmentProposal,
}
#[derive(serde::Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Transaction {
pub pay_method: TransactionPayMethod,
pub payment_flow: String,
}
#[derive(serde::Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Transactions {
pub transactions: Vec<Transaction>,
}
#[derive(serde::Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Order {
/// Example: "{orderId}",
pub order_id: super::OrderId,
/// Example: "358766",
pub ext_order_id: Option<String>,
/// Example: "2014-10-27T14:58:17.443+01:00",
pub order_create_date: String,
/// Example: "http://localhost/OrderNotify/",
pub notify_url: Option<String>,
/// Example: "127.0.0.1",
pub customer_ip: String,
/// Example: "145227",
pub merchant_pos_id: String,
/// Example: "New order",
pub description: String,
/// Example: "PLN",
pub currency_code: String,
/// Example: "3200",
pub total_amount: String,
/// Example: "NEW",
pub status: String,
/// Example: `[{"name":"Product1","unitPrice":"1000","quantity":"1"}]`
pub products: Vec<super::Product>,
}
#[derive(serde::Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct OrdersInfo {
pub orders: Vec<Order>,
pub status: Status,
pub properties: Option<Vec<crate::Prop>>,
}
#[derive(serde::Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct OrderInfo {
pub order: Order,
pub status: Status,
pub properties: Option<Vec<crate::Prop>>,
}

View File

@ -1,25 +0,0 @@
use std::fmt::Display;
pub(crate) fn serialize_i32<S>(v: &i32, ser: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
ser.serialize_str(&format!("{v}"))
}
pub(crate) fn serialize_newtype<N: Display, S>(
v: &N,
ser: S,
) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
ser.serialize_str(&format!("{v}"))
}
pub(crate) fn serialize_u32<S>(v: &u32, ser: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
ser.serialize_str(&format!("{v}"))
}

View File

@ -1,17 +0,0 @@
{
"orderId": "ZXWZ53KQQM200702GUEST000P01",
"refund": {
"refundId": "5000009987",
"extRefundId": "20200702091903",
"amount": "21000",
"currencyCode": "PLN",
"description": "5000009987 Refund Accepted",
"creationDateTime": "2020-07-02T09:19:03.896+02:00",
"status": "PENDING",
"statusDateTime": "2020-07-02T09:19:04.013+02:00"
},
"status": {
"statusCode": "SUCCESS",
"statusDesc": "Refund queued for processing"
}
}

View File

@ -1,21 +0,0 @@
{
"order": {
"orderId": "LDLW5N7MF4140324GUEST000P01",
"extOrderId": "Order id in your shop",
"orderCreateDate": "2012-12-31T12:00:00",
"notifyUrl": "http://tempuri.org/notify",
"customerIp": "127.0.0.1",
"merchantPosId": "98374",
"description": "My order description",
"currencyCode": "PLN",
"totalAmount": "200",
"products": [
{
"name": "Product 1",
"unitPrice": "200",
"quantity": "1"
}
],
"status": "CANCELED"
}
}

View File

@ -1,38 +0,0 @@
{
"order": {
"orderId": "LDLW5N7MF4140324GUEST000P01",
"extOrderId": "Order id in your shop",
"orderCreateDate": "2012-12-31T12:00:00",
"notifyUrl": "http://tempuri.org/notify",
"customerIp": "127.0.0.1",
"merchantPosId": "238684",
"description": "My order description",
"currencyCode": "PLN",
"totalAmount": "200",
"buyer": {
"email": "john.doe@example.org",
"phone": "111111111",
"firstName": "John",
"lastName": "Doe",
"language": "en"
},
"payMethod": {
"type": "CARD_TOKEN"
},
"products": [
{
"name": "Product 1",
"unitPrice": "200",
"quantity": "1"
}
],
"status": "COMPLETED"
},
"localReceiptDateTime": "2016-03-02T12:58:14.828+01:00",
"properties": [
{
"name": "PAYMENT_ID",
"value": "151471228"
}
]
}

View File

@ -1,38 +0,0 @@
{
"order": {
"orderId": "LDLW5N7MF4140324GUEST000P01",
"extOrderId": "Order id in your shop",
"orderCreateDate": "2012-12-31T12:00:00",
"notifyUrl": "http://tempuri.org/notify",
"customerIp": "127.0.0.1",
"merchantPosId": "8236",
"description": "My order description",
"currencyCode": "PLN",
"totalAmount": "200",
"buyer": {
"email": "john.doe@example.org",
"phone": "111111111",
"firstName": "John",
"lastName": "Doe",
"language": "en"
},
"payMethod": {
"type": "INSTALLMENTS"
},
"products": [
{
"name": "Product 1",
"unitPrice": "200",
"quantity": "1"
}
],
"status": "COMPLETED"
},
"localReceiptDateTime": "2016-03-02T12:58:14.828+01:00",
"properties": [
{
"name": "PAYMENT_ID",
"value": "151471228"
}
]
}

View File

@ -1,38 +0,0 @@
{
"order": {
"orderId": "LDLW5N7MF4140324GUEST000P01",
"extOrderId": "Order id in your shop",
"orderCreateDate": "2012-12-31T12:00:00",
"notifyUrl": "http://tempuri.org/notify",
"customerIp": "127.0.0.1",
"merchantPosId": "928374",
"description": "My order description",
"currencyCode": "PLN",
"totalAmount": "200",
"buyer": {
"email": "john.doe@example.org",
"phone": "111111111",
"firstName": "John",
"lastName": "Doe",
"language": "en"
},
"payMethod": {
"type": "PBL"
},
"products": [
{
"name": "Product 1",
"unitPrice": "200",
"quantity": "1"
}
],
"status": "COMPLETED"
},
"localReceiptDateTime": "2016-03-02T12:58:14.828+01:00",
"properties": [
{
"name": "PAYMENT_ID",
"value": "151471228"
}
]
}

View File

@ -1,9 +0,0 @@
{
"status": {
"statusCode": "ERROR_VALUE_MISSING",
"severity": "ERROR",
"code": "8300",
"codeLiteral": "FOO_BAR",
"statusDesc": "Implementation changed"
}
}

View File

@ -1,14 +0,0 @@
{
"orderId": "2DVZMPMFPN140219GUEST000P01",
"extOrderId": "Order id in your shop",
"refund": {
"refundId": "912128",
"amount": "15516",
"currencyCode": "PLN",
"status": "FINALIZED",
"statusDateTime": "1395677071799",
"reason": "refund",
"reasonDescription": "on customers request",
"refundDate": "1395677071799"
}
}

View File

@ -1,9 +0,0 @@
{
"status": {
"statusCode": "ERROR_VALUE_MISSING",
"severity": "ERROR",
"code": "8300",
"codeLiteral": "MISSING_REFUND_SECTION",
"statusDesc": "Missing required field"
}
}