pay_u 0.1.9

PayU Rest API wrapper
Documentation
//! 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>,
}