diff --git a/src/api/invoice.rs b/src/api/invoice.rs index 74e7844..611a5a6 100644 --- a/src/api/invoice.rs +++ b/src/api/invoice.rs @@ -27,10 +27,12 @@ use crate::{ /// For example, the next invoice number after `INVOICE-1234` is `INVOICE-1235`. #[derive(Debug, Default, Clone)] pub struct GenerateInvoiceNumber { + /// The invoice number. If you omit this value, the default is the auto-incremented number from the last number. pub invoice_number: Option, } impl GenerateInvoiceNumber { + /// New constructor. pub fn new(invoice_number: Option) -> Self { Self { invoice_number } } @@ -60,10 +62,12 @@ impl Endpoint for GenerateInvoiceNumber { /// Include invoice details including merchant information. The invoice object must include an items array. #[derive(Debug, Clone)] pub struct CreateDraftInvoice { + /// The invoice details. pub invoice: InvoicePayload, } impl CreateDraftInvoice { + /// New constructor. pub fn new(invoice: InvoicePayload) -> Self { Self { invoice } } @@ -89,13 +93,15 @@ impl Endpoint for CreateDraftInvoice { } } -/// Get an invoice by ID. +/// Shows details for an invoice, by ID. #[derive(Debug, Clone)] pub struct GetInvoice { + /// The invoice id. pub invoice_id: String, } impl GetInvoice { + /// New constructor. pub fn new(invoice_id: String) -> Self { Self { invoice_id } } @@ -117,14 +123,16 @@ impl Endpoint for GetInvoice { } } -/// List invoices +/// Lists invoices. To filter the invoices that appear in the response, you can specify one or more optional query parameters. /// Page size has the following limits: [1, 100]. #[derive(Debug, Clone)] pub struct ListInvoices { + /// The endpoint query. pub query: Query, } impl ListInvoices { + /// New constructor. pub fn new(query: Query) -> Self { Self { query } } @@ -150,13 +158,19 @@ impl Endpoint for ListInvoices { } } -/// Delete an invoice +/// Deletes a draft or scheduled invoice, by ID. Deletes invoices in the draft or scheduled state only. +/// +/// For invoices that have already been sent, you can cancel the invoice. +/// +/// After you delete a draft or scheduled invoice, you can no longer use it or show its details. However, you can reuse its invoice number. #[derive(Debug, Clone)] pub struct DeleteInvoice { + /// The invocie id. pub invoice_id: String, } impl DeleteInvoice { + /// New constructor. pub fn new(invoice_id: String) -> Self { Self { invoice_id } } @@ -178,9 +192,12 @@ impl Endpoint for DeleteInvoice { } } +/// The update invoice query. #[derive(Debug, Clone, Serialize, Builder)] pub struct UpdateInvoiceQuery { + /// Indicates whether to send the invoice update notification to the recipient. pub send_to_recipient: bool, + /// Indicates whether to send the invoice update notification to the merchant. pub send_to_invoicer: bool, } @@ -189,11 +206,14 @@ pub struct UpdateInvoiceQuery { /// Fully updates an invoice, by ID. In the JSON request body, include a complete invoice object. This call does not support partial updates. #[derive(Debug, Clone)] pub struct UpdateInvoice { + /// The updated invoice object. pub invoice: Invoice, + /// The update invoice query. pub query: UpdateInvoiceQuery, } impl UpdateInvoice { + /// New constructor. pub fn new(invoice: Invoice, query: UpdateInvoiceQuery) -> Self { Self { invoice, @@ -226,14 +246,17 @@ impl Endpoint for UpdateInvoice { } } -/// Cancel an invoice. +/// Cancels a sent invoice, by ID, and, optionally, sends a notification about the cancellation to the payer, merchant, and CC: emails. #[derive(Debug, Clone)] pub struct CancelInvoice { + /// The invoice id. pub invoice_id: String, + /// The reason of the cancelation. pub reason: CancelReason } impl CancelInvoice { + /// New constructor. pub fn new(invoice_id: String, reason: CancelReason) -> Self { Self { invoice_id, diff --git a/src/api/mod.rs b/src/api/mod.rs index bc9b094..778d0a3 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,2 +1,4 @@ +//! This module contains the api endpoints. + pub mod orders; pub mod invoice; \ No newline at end of file diff --git a/src/api/orders.rs b/src/api/orders.rs index f73ded3..ece2ee6 100644 --- a/src/api/orders.rs +++ b/src/api/orders.rs @@ -4,17 +4,24 @@ use std::borrow::Cow; +use derive_builder::Builder; +use serde::Serialize; +use serde_json::json; + use crate::{ data::orders::{Order, OrderPayload, PaymentSourceResponse}, endpoint::Endpoint, }; +/// Creates an order. #[derive(Debug)] pub struct CreateOrder { - order: OrderPayload, + /// The order payload. + pub order: OrderPayload, } impl CreateOrder { + /// New constructor. pub fn new(order: OrderPayload) -> Self { Self { order } } @@ -42,12 +49,15 @@ impl Endpoint for CreateOrder { // TODO: Update order. +/// Query an order by id. #[derive(Debug)] pub struct ShowOrderDetails { - order_id: String, + /// The order id. + pub order_id: String, } impl ShowOrderDetails { + /// New constructor. pub fn new(order_id: &str) -> Self { Self { order_id: order_id.to_string(), @@ -71,16 +81,48 @@ impl Endpoint for ShowOrderDetails { } } -#[derive(Debug)] +/// The payment source used to fund the payment. +#[derive(Debug, Serialize, Builder, Clone)] +pub struct PaymentSourceToken { + /// The PayPal-generated ID for the token. + pub id: String, + /// The tokenization method that generated the ID. + /// + /// Can only be BILLING_AGREEMENT. + pub r#type: String, +} + +/// Payment source used in the capture order endpoint. +#[derive(Debug, Serialize, Builder, Clone)] +pub struct PaymentSource { + /// The tokenized payment source to fund a payment. + pub token: PaymentSourceToken, +} + +/// The capture order endpoint body. +#[derive(Debug, Serialize, Clone)] +pub struct PaymentSourceBody { + /// The payment source definition. + pub payment_source: PaymentSource, +} + +/// Captures payment for an order. To successfully capture payment for an order, +/// the buyer must first approve the order or a valid payment_source must be provided in the request. +/// A buyer can approve the order upon being redirected to the rel:approve URL that was returned in the HATEOAS links in the create order response. +#[derive(Debug, Clone, Builder)] pub struct CaptureOrder { - order_id: String, - // TODO: payment source? https://developer.paypal.com/docs/api/orders/v2/#orders_capture + /// The id of the order. + pub order_id: String, + /// The endpoint body. + pub body: Option } impl CaptureOrder { + /// New constructor. pub fn new(order_id: &str) -> Self { Self { order_id: order_id.to_string(), + body: None, } } } @@ -88,7 +130,7 @@ impl CaptureOrder { impl Endpoint for CaptureOrder { type Query = (); - type Body = (); + type Body = PaymentSourceBody; type Response = Order; @@ -99,18 +141,29 @@ impl Endpoint for CaptureOrder { fn method(&self) -> reqwest::Method { reqwest::Method::POST } + + fn body(&self) -> Option<&Self::Body> { + self.body.as_ref() + } } +/// Authorizes payment for an order. To successfully authorize payment for an order, +/// the buyer must first approve the order or a valid payment_source must be provided in the request. +/// A buyer can approve the order upon being redirected to the rel:approve URL that was returned in the HATEOAS links in the create order response. #[derive(Debug)] pub struct AuthorizeOrder { + /// The order id. order_id: String, - // TODO: payment source? https://developer.paypal.com/docs/api/orders/v2/#orders_authorize + /// The endpoint body. + pub body: Option } impl AuthorizeOrder { + /// New constructor. pub fn new(order_id: &str) -> Self { Self { order_id: order_id.to_string(), + body: None, } } } @@ -118,7 +171,7 @@ impl AuthorizeOrder { impl Endpoint for AuthorizeOrder { type Query = (); - type Body = (); + type Body = PaymentSourceBody; type Response = Order; @@ -129,6 +182,10 @@ impl Endpoint for AuthorizeOrder { fn method(&self) -> reqwest::Method { reqwest::Method::POST } + + fn body(&self) -> Option<&Self::Body> { + self.body.as_ref() + } } #[cfg(test)] diff --git a/src/client.rs b/src/client.rs index 7331a93..97abf72 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,3 +1,5 @@ +//! The paypal api wrapper client, which holds the http request client. + use reqwest::header::{self, HeaderMap}; use serde::Deserialize; use std::time::Duration; @@ -186,6 +188,7 @@ impl Client { } } + /// Executes the given endpoint with the given headers. pub async fn execute_ext(&self, endpoint: E, headers: HeaderParams) -> Result where E: Endpoint, @@ -214,6 +217,9 @@ impl Client { } } + /// Executes the given endpoints with the default headers. + /// + /// You must remember to call `get_access_token` first or this may fail due to not being authed. pub async fn execute(&self, endpoint: E) -> Result where E: Endpoint, diff --git a/src/data/invoice.rs b/src/data/invoice.rs index 8d6e240..e58992e 100644 --- a/src/data/invoice.rs +++ b/src/data/invoice.rs @@ -1,3 +1,5 @@ +//! Paypal object definitions used in the invoice api. + use crate::{data::common::*, data::common::LinkDescription}; use derive_builder::Builder; use serde::{Deserialize, Serialize}; diff --git a/src/data/mod.rs b/src/data/mod.rs index cab894e..ecc762c 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -1,3 +1,5 @@ +//! This module contains the data structures used in the api endpoints. + pub mod common; pub mod orders; pub mod invoice; \ No newline at end of file diff --git a/src/data/orders.rs b/src/data/orders.rs index efdb0cd..0beb13a 100644 --- a/src/data/orders.rs +++ b/src/data/orders.rs @@ -1,3 +1,5 @@ +//! Paypal object definitions used by the orders api. + use super::common::*; use crate::errors::{PaypalError, ResponseError}; use crate::HeaderParams; @@ -719,7 +721,9 @@ pub struct Order { pub links: Vec, } +/// An invoice number. #[derive(Debug, Serialize, Deserialize, Clone)] pub struct InvoiceNumber { + /// The invoice number. pub invoice_number: String, } \ No newline at end of file diff --git a/src/endpoint.rs b/src/endpoint.rs index d152045..4600678 100644 --- a/src/endpoint.rs +++ b/src/endpoint.rs @@ -1,26 +1,37 @@ +//! This module contains the endpoint trait used to implemented api endpoints. + use std::borrow::Cow; use serde::{Serialize, de::DeserializeOwned}; use crate::{SANDBOX_ENDPOINT, LIVE_ENDPOINT}; +/// A trait implemented by api endpoints. pub trait Endpoint { + /// The serializable query type. type Query: Serialize; + /// The serializable body type. type Body: Serialize; + /// The deserializable response type. type Response: DeserializeOwned; - // The endpoint relative path. Must start with a `/` + /// The endpoint relative path. Must start with a `/` fn relative_path(&self) -> Cow; - // The request method. + /// The request method of this endpoint. fn method(&self) -> reqwest::Method; + /// The query to be used when calling this endpoint. fn query(&self) -> Option<&Self::Query> { None } + /// The body to be used when calling this endpoint. fn body(&self) -> Option<&Self::Body> { None } + /// The full path of this endpoint. + /// + /// Automatically implemented. fn full_path(&self, is_sandbox: bool) -> String { if is_sandbox { format!("{}{}", SANDBOX_ENDPOINT, self.relative_path()) diff --git a/src/lib.rs b/src/lib.rs index 22a2b9f..d7ee75e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,7 +74,7 @@ //! - [ ] Webhooks Management API - 0.14.0 //! - [ ] Payment Experience Web Profiles API - 1.0.0 -//#![deny(missing_docs)] +#![deny(missing_docs)] pub mod api; pub mod countries;