Add many additional create order fields
This commit is contained in:
parent
9658abe3b8
commit
94e7e7eb1e
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2135,7 +2135,7 @@ checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc"
|
||||
|
||||
[[package]]
|
||||
name = "pay_u"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"derive_more",
|
||||
|
@ -153,8 +153,12 @@ pub(crate) async fn request_payment(
|
||||
client
|
||||
.lock()
|
||||
.create_order(
|
||||
OrderCreateRequest::new(msg.buyer.into(), msg.customer_ip, msg.currency)
|
||||
.with_description(msg.description)
|
||||
OrderCreateRequest::build(
|
||||
msg.buyer.into(),
|
||||
msg.customer_ip,
|
||||
msg.currency,
|
||||
msg.description,
|
||||
)?
|
||||
.with_notify_url(msg.redirect_uri)
|
||||
.with_products(msg.products.into_iter().map(Into::into)),
|
||||
)
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "pay_u"
|
||||
description = "PayU Rest API wrapper"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
|
@ -17,11 +17,13 @@ async fn usage() {
|
||||
client.authorize().await.expect("Invalid credentials");
|
||||
|
||||
let _res = client.create_order(
|
||||
OrderCreateRequest::new(
|
||||
OrderCreateRequest::build(
|
||||
Buyer::new("john.doe@example.com", "654111654", "John", "Doe", "pl"),
|
||||
"127.0.0.1",
|
||||
"PLN",
|
||||
"Some description"
|
||||
)
|
||||
.expect("All required fields must be valid")
|
||||
// Endpoint which will be requested by PayU with payment status update
|
||||
.with_notify_url("https://your.eshop.com/notify")
|
||||
// payment description (MANDATORY)
|
||||
@ -94,6 +96,10 @@ async fn handle_notification(path: Path<i32>, Json(notify): Json<pay_u::notify::
|
||||
}
|
||||
```
|
||||
|
||||
### Releases
|
||||
|
||||
0.1.7 - Added credit and more create order request options like additional description, visible description.
|
||||
|
||||
## Bugs
|
||||
|
||||
Please report bugs here: https://todo.sr.ht/~tsumanu/payu-rs
|
||||
|
439
pay_u/src/lib.rs
439
pay_u/src/lib.rs
@ -198,19 +198,86 @@ pub enum RefundStatus {
|
||||
Completed,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Delivery {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
/// Street name
|
||||
street: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
/// Postal box number
|
||||
postal_box: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
/// Postal code
|
||||
postal_code: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
/// City
|
||||
city: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
/// Province
|
||||
state: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
/// Two-letter country code compliant with ISO-3166.
|
||||
country_code: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
/// Address description
|
||||
name: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
/// Recipient’s name
|
||||
recipient_name: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
/// Recipient’s e-mail address
|
||||
recipient_email: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
/// Recipient’s phone number
|
||||
recipient_phone: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BuyerShippingAddress {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
/// stores the shipping address
|
||||
delivery: Option<Delivery>,
|
||||
}
|
||||
|
||||
impl BuyerShippingAddress {
|
||||
pub fn new_with_delivery(delivery: Delivery) -> Self {
|
||||
Self {
|
||||
delivery: Some(delivery),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Buyer {
|
||||
/// Required customer e-mail
|
||||
email: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
email: Option<String>,
|
||||
/// Required customer phone number
|
||||
phone: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
phone: Option<String>,
|
||||
/// Required customer first name
|
||||
first_name: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
first_name: Option<String>,
|
||||
/// Required customer last name
|
||||
last_name: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
last_name: Option<String>,
|
||||
/// Required customer language
|
||||
language: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
language: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
delivery: Option<BuyerShippingAddress>,
|
||||
}
|
||||
|
||||
impl Buyer {
|
||||
@ -229,62 +296,68 @@ impl Buyer {
|
||||
Language: Into<String>,
|
||||
{
|
||||
Self {
|
||||
email: email.into(),
|
||||
phone: phone.into(),
|
||||
first_name: first_name.into(),
|
||||
last_name: last_name.into(),
|
||||
language: lang.into(),
|
||||
email: Some(email.into()),
|
||||
phone: Some(phone.into()),
|
||||
first_name: Some(first_name.into()),
|
||||
last_name: Some(last_name.into()),
|
||||
language: Some(lang.into()),
|
||||
delivery: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn email(&self) -> &str {
|
||||
&self.email
|
||||
self.email.as_deref().unwrap_or_default()
|
||||
}
|
||||
pub fn with_email<S>(mut self, email: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
self.email = email.into();
|
||||
self.email = Some(email.into());
|
||||
self
|
||||
}
|
||||
pub fn phone(&self) -> &str {
|
||||
&self.phone
|
||||
self.phone.as_deref().unwrap_or_default()
|
||||
}
|
||||
pub fn with_phone<S>(mut self, phone: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
self.phone = phone.into();
|
||||
self.phone = Some(phone.into());
|
||||
self
|
||||
}
|
||||
pub fn first_name(&self) -> &str {
|
||||
&self.first_name
|
||||
self.first_name.as_deref().unwrap_or_default()
|
||||
}
|
||||
pub fn with_first_name<S>(mut self, first_name: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
self.first_name = first_name.into();
|
||||
self.first_name = Some(first_name.into());
|
||||
self
|
||||
}
|
||||
pub fn last_name(&self) -> &str {
|
||||
&self.last_name
|
||||
self.last_name.as_deref().unwrap_or_default()
|
||||
}
|
||||
pub fn with_last_name<S>(mut self, last_name: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
self.last_name = last_name.into();
|
||||
self.last_name = Some(last_name.into());
|
||||
self
|
||||
}
|
||||
pub fn language(&self) -> &str {
|
||||
&self.language
|
||||
self.language.as_deref().unwrap_or_default()
|
||||
}
|
||||
pub fn with_language<S>(mut self, language: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
self.language = language.into();
|
||||
self.language = Some(language.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_delivery(mut self, delivery: Delivery) -> Self {
|
||||
self.delivery = Some(BuyerShippingAddress::new_with_delivery(delivery));
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -306,6 +379,14 @@ pub struct Product {
|
||||
deserialize_with = "deserialize::deserialize_u32"
|
||||
)]
|
||||
pub quantity: Quantity,
|
||||
/// Product type, which can be virtual or material; (possible values true or
|
||||
/// false).
|
||||
#[serde(rename = "virtual", skip_serializing_if = "Option::is_none")]
|
||||
pub virtual_product: Option<bool>,
|
||||
/// Marketplace date from which the product (or offer) is available, ISO
|
||||
/// format applies, e.g. "2019-03-27T10:57:59.000+01:00".
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub listing_date: Option<chrono::NaiveDateTime>,
|
||||
}
|
||||
|
||||
impl Product {
|
||||
@ -314,8 +395,238 @@ impl Product {
|
||||
name: name.into(),
|
||||
unit_price,
|
||||
quantity,
|
||||
virtual_product: None,
|
||||
listing_date: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Product type, which can be virtual or material; (possible values true or
|
||||
/// false).
|
||||
pub fn into_virtual(mut self) -> Self {
|
||||
self.virtual_product = Some(true);
|
||||
self
|
||||
}
|
||||
|
||||
/// Product type, which can be virtual or material; (possible values true or
|
||||
/// false).
|
||||
pub fn non_virtual(mut self) -> Self {
|
||||
self.virtual_product = Some(false);
|
||||
self
|
||||
}
|
||||
|
||||
/// Marketplace date from which the product (or offer) is available, ISO
|
||||
/// format applies, e.g. "2019-03-27T10:57:59.000+01:00".
|
||||
pub fn with_listing_date(mut self, listing_date: chrono::NaiveDateTime) -> Self {
|
||||
self.listing_date = Some(listing_date);
|
||||
self
|
||||
}
|
||||
|
||||
fn erase_listing_date(mut self) -> Self {
|
||||
self.listing_date = None;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ShoppingCart {
|
||||
/// Section containing data of shipping method.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
shopping_method: Option<ShoppingMethod>,
|
||||
/// Section containing data about ordered products.
|
||||
/// > Note: product objects in the <shoppingCart.products> section do not
|
||||
/// > have a listingDate field
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
products: Option<Vec<Product>>,
|
||||
/// Submerchant identifier. This field should be consistent with field
|
||||
/// extCustomerId in shoppingCarts section when order is placed in
|
||||
/// marketplace.
|
||||
ext_customer_id: String,
|
||||
}
|
||||
|
||||
impl ShoppingCart {
|
||||
pub fn new<ExtCustomerId, Products>(ext_customer_id: ExtCustomerId) -> Self
|
||||
where
|
||||
ExtCustomerId: Into<String>,
|
||||
{
|
||||
Self {
|
||||
shopping_method: None,
|
||||
ext_customer_id: ext_customer_id.into(),
|
||||
products: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_with_products<ExtCustomerId, Products>(
|
||||
ext_customer_id: ExtCustomerId,
|
||||
products: Products,
|
||||
) -> Self
|
||||
where
|
||||
ExtCustomerId: Into<String>,
|
||||
Products: Iterator<Item = Product>,
|
||||
{
|
||||
Self {
|
||||
shopping_method: None,
|
||||
ext_customer_id: ext_customer_id.into(),
|
||||
products: Some(products.map(Product::erase_listing_date).collect()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_products<Products>(mut self, products: Products) -> Self
|
||||
where
|
||||
Products: Iterator<Item = Product>,
|
||||
{
|
||||
self.products = Some(products.map(Product::erase_listing_date).collect());
|
||||
self
|
||||
}
|
||||
|
||||
/// Section containing data of shipping method.
|
||||
pub fn shopping_method(&self) -> &Option<ShoppingMethod> {
|
||||
&self.shopping_method
|
||||
}
|
||||
|
||||
/// Section containing data about ordered products.
|
||||
/// > Note: product objects in the <shoppingCart.products> section do not
|
||||
/// > have a listingDate field
|
||||
pub fn products(&self) -> &Option<Vec<Product>> {
|
||||
&self.products
|
||||
}
|
||||
|
||||
/// Submerchant identifier. This field should be consistent with field
|
||||
/// extCustomerId in shoppingCarts section when order is placed in
|
||||
/// marketplace.
|
||||
pub fn ext_customer_id(&self) -> &String {
|
||||
&self.ext_customer_id
|
||||
}
|
||||
}
|
||||
|
||||
/// Type of shipment
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||
pub enum ShoppingMethodType {
|
||||
Courier,
|
||||
CollectionPointPickup,
|
||||
ParcelLocker,
|
||||
StorePickup,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Address {
|
||||
/// The full name of the pickup point, including its unique identifier, e.g.
|
||||
/// „Parcel locker POZ29A”.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub point_id: Option<String>,
|
||||
/// Street name, possibly including house and flat number.
|
||||
/// Recommended
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub street: Option<String>,
|
||||
/// Street number
|
||||
/// Recommended
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub street_no: Option<String>,
|
||||
/// Flat number
|
||||
/// Recommended
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub flat_no: Option<String>,
|
||||
/// Postal code
|
||||
/// Recommended
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub postal_code: Option<String>,
|
||||
/// City
|
||||
/// Recommended
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub city: Option<String>,
|
||||
/// Two-letter country code compliant with ISO-3166
|
||||
/// Recommended
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub country_code: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ShoppingMethod {
|
||||
/// Shipping type
|
||||
/// Recommended
|
||||
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
|
||||
pub shopping_type: Option<ShoppingMethodType>,
|
||||
/// Shipping cost
|
||||
/// Recommended
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub price: Option<String>,
|
||||
/// Section containing data about shipping address.
|
||||
/// Recommended
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub address: Option<Address>,
|
||||
}
|
||||
|
||||
#[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>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Applicant {
|
||||
/// Applicant’s email address
|
||||
/// Recommended
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
email: Option<String>,
|
||||
/// Applicant’s phone number
|
||||
/// Recommended
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
phone: Option<String>,
|
||||
/// Applicant’s first name
|
||||
/// Recommended
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
first_name: Option<String>,
|
||||
/// Applicant’s 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 applicant’s 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>,
|
||||
}
|
||||
|
||||
#[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
|
||||
}
|
||||
}
|
||||
|
||||
/// MultiUseCartToken
|
||||
@ -504,9 +815,12 @@ pub struct OrderCreateRequest {
|
||||
/// 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")]
|
||||
statement_description: Option<String>,
|
||||
#[serde(flatten, skip_serializing_if = "Option::is_none")]
|
||||
muct: Option<muct::MultiUseCartToken>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
credit: Option<Credit>,
|
||||
}
|
||||
|
||||
impl OrderCreateRequest {
|
||||
@ -542,6 +856,7 @@ impl OrderCreateRequest {
|
||||
visible_description: None,
|
||||
statement_description: None,
|
||||
muct: None,
|
||||
credit: None,
|
||||
})
|
||||
}
|
||||
|
||||
@ -560,26 +875,6 @@ impl OrderCreateRequest {
|
||||
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
|
||||
}
|
||||
|
||||
pub fn with_multi_use_token(
|
||||
mut self,
|
||||
recurring: muct::Recurring,
|
||||
@ -613,6 +908,9 @@ impl OrderCreateRequest {
|
||||
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>,
|
||||
@ -621,6 +919,38 @@ impl OrderCreateRequest {
|
||||
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
|
||||
///
|
||||
@ -635,6 +965,28 @@ impl OrderCreateRequest {
|
||||
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.
|
||||
///
|
||||
@ -675,25 +1027,30 @@ impl OrderCreateRequest {
|
||||
&self.customer_ip
|
||||
}
|
||||
|
||||
///
|
||||
pub fn merchant_pos_id(&self) -> 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) -> &Price {
|
||||
&self.total_amount
|
||||
}
|
||||
|
||||
pub fn buyer(&self) -> &Option<Buyer> {
|
||||
&self.buyer
|
||||
}
|
||||
|
||||
pub fn products(&self) -> &[Product] {
|
||||
&self.products
|
||||
}
|
||||
|
||||
pub fn order_create_date(&self) -> &Option<String> {
|
||||
&self.order_create_date
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user