diff --git a/src/common.rs b/src/common.rs index 5394ce1..9a9bada 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,4 +1,4 @@ -/// Common paypal object definitions used amon 2 or more APIs +//! Common paypal object definitions used amon 2 or more APIs use serde::{Serialize, Deserialize}; @@ -79,4 +79,30 @@ pub struct Money { /// /// For the required number of decimal places for a currency code, see [Currency Codes](https://developer.paypal.com/docs/api/reference/currency-codes/). pub value: String, -} \ No newline at end of file +} + +#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +#[allow(missing_docs)] +pub enum LinkMethod { + Get, + Post, + Put, + Delete, + Head, + Connect, + Options, + Patch, +} + +/// A HTOAES link +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct LinkDescription { + /// The complete target URL. + pub href: String, + /// The link relation type, which serves as an ID for a link that unambiguously describes the semantics of the link. + pub rel: String, + /// The HTTP method required to make the related call. + #[serde(skip_serializing_if = "Option::is_none")] + pub method: Option, +} diff --git a/src/errors.rs b/src/errors.rs index e0df4f7..e312508 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use std::fmt; use std::error::Error; use serde::{Deserialize, Serialize}; -use crate::objects::LinkDescription; +use crate::common::LinkDescription; /// A paypal api response error. #[derive(Debug, Serialize, Deserialize)] diff --git a/src/invoice.rs b/src/invoice.rs index a87e758..956866e 100644 --- a/src/invoice.rs +++ b/src/invoice.rs @@ -381,6 +381,7 @@ pub struct ShippingCost { pub tax: Option, } +/// The custom amount to apply to an invoice #[derive(Debug, Default, Serialize, Deserialize)] pub struct CustomAmount { /// The label to the custom amount of the invoice. @@ -469,6 +470,7 @@ pub enum PaymentMethod { Other, } +/// Payment detail #[derive(Debug, Serialize, Deserialize)] pub struct PaymentDetail { /// The payment type in an invoicing flow which can be PayPal or an external cash or check payment. @@ -493,6 +495,7 @@ pub struct PaymentDetail { pub shipping_info: Option, } +/// Payments registered against the invoice #[derive(Debug, Default, Serialize, Deserialize)] pub struct Payments { /// The aggregated payment amounts against this invoice. @@ -505,7 +508,69 @@ pub struct Payments { pub transactions: Option>, } -/// An invoice +/// Refund details +#[derive(Debug, Serialize, Deserialize)] +pub struct RefundDetail { + /// The PayPal refund type. Indicates whether the refund was paid through PayPal or externally in the invoicing flow. + #[serde(skip_serializing_if = "Option::is_none")] + pub r#type: Option, + /// The ID for a PayPal payment transaction. Required for the PAYPAL payment type. + #[serde(skip_serializing_if = "Option::is_none")] + pub refund_id: Option, + /// The date when the invoice was refunded, in Internet date format. + #[serde(skip_serializing_if = "Option::is_none")] + pub refund_date: Option>, + /// The amount to record as refunded. If you omit the amount, the total invoice paid amount is recorded as refunded. + #[serde(skip_serializing_if = "Option::is_none")] + pub amount: Option, + /// The payment mode or method through which the invoicer can accept the payments. + pub method: PaymentMethod, +} + +/// List of refunds +#[derive(Debug, Serialize, Deserialize, Default)] +pub struct Refunds { + /// The aggregated refund amounts. + /// Read only. + #[serde(skip_serializing_if = "Option::is_none")] + pub refund_amount: Option, + /// An array of refund details for the invoice. Includes the refund type, date, amount, and method. + /// Read only. + #[serde(skip_serializing_if = "Option::is_none")] + pub transactions: Option>, +} + +/// The status of the invoice +#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub enum Status { + /// The invoice is in draft state. It is not yet sent to the payer. + Draft, + /// The invoice has been sent to the payer. The payment is awaited from the payer. + Sent, + /// The invoice is scheduled on a future date. It is not yet sent to the payer. + Scheduled, + /// The payer has paid for the invoice. + Paid, + /// The invoice is marked as paid by the invoicer. + MarkedAsPaid, + /// The invoice has been cancelled by the invoicer. + Cancelled, + /// The invoice has been refunded by the invoicer. + Refunded, + /// The payer has partially paid for the invoice. + PartiallyPaid, + /// The invoice has been partially refunded by the invoicer. + PartiallyRefunded, + /// The invoice is marked as refunded by the invoicer. + MarkedAsRefunded, + /// The invoicer is yet to receive the payment from the payer for the invoice. + Unpaid, + /// The invoicer is yet to receive the payment for the invoice. It is under pending review. + PaymentPending, +} + +/// An invoice payload #[derive(Debug, Serialize, Deserialize)] pub struct InvoicePayload { /// The details of the invoice. Includes the invoice number, date, payment terms, and audit metadata. @@ -521,13 +586,62 @@ pub struct InvoicePayload { #[serde(skip_serializing_if = "Option::is_none")] pub additional_recipients: Option>, /// An array of invoice line item information. - #[serde(skip_serializing_if = "Option::is_none")] - pub items: Option>, + pub items: Vec, /// The invoice configuration details. Includes partial payment, tip, and tax calculated after discount. #[serde(skip_serializing_if = "Option::is_none")] pub configuration: Option, + /// The invoice amount summary of item total, discount, tax total and shipping.. #[serde(skip_serializing_if = "Option::is_none")] pub amount: Option, + /// List of payments registered against the invoice. + #[serde(skip_serializing_if = "Option::is_none")] + pub payments: Option, + /// List of refunds against this invoice. The invoicing refund details includes refund type, date, amount, and method. + #[serde(skip_serializing_if = "Option::is_none")] + pub refunds: Option, +} + +/// Definition: https://developer.paypal.com/docs/api/invoicing/v2/#invoices_get +#[derive(Debug, Serialize, Deserialize)] +pub struct Invoice { + /// The ID of the invoice. + pub id: String, + /// The parent ID to an invoice that defines the group invoice to which the invoice is related. + #[serde(skip_serializing_if = "Option::is_none")] + pub parent_id: Option, + /// The status of the invoice. + pub status: Status, + /// The details of the invoice. Includes the invoice number, date, payment terms, and audit metadata. + pub detail: InvoiceDetail, + /// The invoicer information. Includes the business name, email, address, phone, fax, tax ID, additional notes, and logo URL. + pub invoicer: InvoicerInfo, + /// The billing and shipping information. Includes name, email, address, phone and language. + pub primary_recipients: Vec, + /// An array of one or more CC: emails to which notifications are sent. + /// If you omit this parameter, a notification is sent to all CC: email addresses that are part of the invoice. + pub additional_recipients: Option>, + /// An array of invoice line item information. + pub items: Option>, + /// The invoice configuration details. Includes partial payment, tip, and tax calculated after discount. + #[serde(skip_serializing_if = "Option::is_none")] + pub configuration: Option, + /// The invoice amount summary of item total, discount, tax total and shipping.. + pub amount: Amount, + /// The due amount, which is the balance amount outstanding after payments. + #[serde(skip_serializing_if = "Option::is_none")] + pub due_amount: Option, + /// The amount paid by the payer as gratuity to the invoicer. + #[serde(skip_serializing_if = "Option::is_none")] + pub gratuity: Option, + /// List of payments registered against the invoice.. + #[serde(skip_serializing_if = "Option::is_none")] + pub payments: Option, + /// List of refunds against this invoice. The invoicing refund details includes refund type, date, amount, and method. + #[serde(skip_serializing_if = "Option::is_none")] + pub refunds: Option, + /// An array of request-related HATEOAS links. + #[serde(skip_serializing_if = "Option::is_none")] + pub links: Option>, } impl super::Client { @@ -555,4 +669,49 @@ impl super::Client { Err(Box::new(res.json::().await?)) } } + + /// Creates a draft invoice. To move the invoice from a draft to payable state, you must send the invoice. + /// Include invoice details including merchant information. The invoice object must include an items array. + pub async fn create_draft_invoice( + &self, + header_params: crate::HeaderParams, + invoice: InvoicePayload, + ) -> Result> { + let build = self.setup_headers( + self.client + .post(format!("{}/v2/invoicing/invoices", self.endpoint()).as_str()), + header_params, + ); + + let res = build.json(&invoice).send().await?; + + if res.status().is_success() { + let x = res.json::().await?; + Ok(x) + } else { + Err(Box::new(res.json::().await?)) + } + } + + /// Get an invoice by ID. + pub async fn get_invoice( + &self, + header_params: crate::HeaderParams, + invoice_id: S, + ) -> Result> { + let build = self.setup_headers( + self.client + .post(format!("{}/v2/invoicing/invoices/{}", self.endpoint(), invoice_id).as_str()), + header_params, + ); + + let res = build.send().await?; + + if res.status().is_success() { + let x = res.json::().await?; + Ok(x) + } else { + Err(Box::new(res.json::().await?)) + } + } } diff --git a/src/orders.rs b/src/orders.rs index da3a500..12c516a 100644 --- a/src/orders.rs +++ b/src/orders.rs @@ -690,32 +690,6 @@ pub struct PaymentSourceResponse { pub wallet: WalletResponse, } -#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)] -#[serde(rename_all = "SCREAMING_SNAKE_CASE")] -#[allow(missing_docs)] -pub enum LinkMethod { - Get, - Post, - Put, - Delete, - Head, - Connect, - Options, - Patch, -} - -/// A HTOAES link -#[derive(Debug, Default, Serialize, Deserialize)] -pub struct LinkDescription { - /// The complete target URL. - pub href: String, - /// The link relation type, which serves as an ID for a link that unambiguously describes the semantics of the link. - pub rel: String, - /// The HTTP method required to make the related call. - #[serde(skip_serializing_if = "Option::is_none")] - pub method: Option, -} - /// The status of an order. #[derive(Debug, Serialize, Deserialize, Eq, PartialEq)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] diff --git a/src/tests.rs b/src/tests.rs index c140fda..0a52c8a 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,5 +1,5 @@ use crate::{ - objects::*, + orders::*, Client, HeaderParams, Prefer, }; use std::env;