paypal_rs/
lib.rs

1//!
2//! [![Version](https://img.shields.io/crates/v/paypal-rs)](https://crates.io/crates/paypal-rs)
3//! [![Downloads](https://img.shields.io/crates/d/paypal-rs)](https://crates.io/crates/paypal-rs)
4//! [![License](https://img.shields.io/crates/l/paypal-rs)](https://crates.io/crates/paypal-rs)
5//! ![Rust](https://github.com/edg-l/paypal-rs/workflows/Rust/badge.svg)
6//! [![Docs](https://docs.rs/paypal-rs/badge.svg)](https://docs.rs/paypal-rs)
7//!
8//! A rust library that wraps the [paypal api](https://developer.paypal.com/docs/api) asynchronously in a strongly typed manner.
9//!
10//! If there is a missing endpoint that you need, you may try to implement the [Endpoint](endpoint::Endpoint) and pass it to [Client::execute](client::Client::execute)
11//!
12//! Currently in early development.
13//!
14
15//! ## Example
16//!
17//! ```no_run
18//! use paypal_rs::{
19//!     Client,
20//!     api::orders::*,
21//!     data::orders::*,
22//!     data::common::Currency,
23//!     PaypalEnv,
24//! };
25//!
26//! #[tokio::main]
27//! async fn main() {
28//!     dotenvy::dotenv().ok();
29//!     let clientid = std::env::var("PAYPAL_CLIENTID").unwrap();
30//!     let secret = std::env::var("PAYPAL_SECRET").unwrap();
31//!
32//!     let mut client = Client::new(clientid, secret, PaypalEnv::Sandbox);
33//!
34//!     client.get_access_token().await.unwrap();
35//!
36//!     let order = OrderPayloadBuilder::default()
37//!         .intent(Intent::Authorize)
38//!         .purchase_units(vec![PurchaseUnit::new(Amount::new(Currency::EUR, "10.0"))])
39//!         .build().unwrap();
40//!
41//!     let create_order = CreateOrder::new(order);
42//!    
43//!     let _order_created = client
44//!         .execute(&create_order).await.unwrap();
45//! }
46//! ```
47//!
48//! ## Testing
49//! You need the enviroment variables PAYPAL_CLIENTID and PAYPAL_SECRET to be set.
50//!
51//! `cargo test`
52//!
53//! ## Roadmap
54//!
55//! - [x] Orders API - 0.1.0
56//! - - [x] Create order
57//! - - [x] Update order
58//! - - [x] Show order details
59//! - - [x] Authorize payment for order
60//! - - [x] Capture payment for order
61//! - [x] Invoicing API - 0.2.0
62//! - - [x] Generate Invoice number
63//! - - [x] Create Draft Invoice
64//! - - [x] Show Invoice Details (Get Invoice)
65//! - - [x] List Invoices
66//! - - [x] Delete Invoice
67//! - - [x] Update Invoice
68//! - - [x] Cancel Invoice
69//! - - [x] Send Invoice
70//! - - [ ] Send Invoice Reminder
71//! - - [ ] List Templates
72//! - - [ ] Create Template
73//! - - [ ] Delete Template
74//! - - [ ] Fully Update Template
75//! - - [ ] Show Template Template
76//! - [ ] Payments API - 0.3.0
77//! - [ ] Tracking API - 0.4.0
78//! - [ ] Subscriptions API - 0.5.0
79//! - [ ] Identity API - 0.6.0
80//! - [ ] Disputes API - 0.7.0
81//! - [ ] Catalog Products API - 0.8.0
82//! - [ ] Partner Referrals API - 0.9.0
83//! - [ ] Payouts API - 0.10.0
84//! - [ ] Transaction Search API - 0.11.0
85//! - [ ] Referenced Payouts API - 0.12.0
86//! - [ ] Vault API - 0.13.0
87//! - [ ] Webhooks Management API - 0.14.0
88//! - [ ] Payment Experience Web Profiles API - 1.0.0
89
90#![deny(missing_docs)]
91#![forbid(unsafe_code)]
92
93pub mod api;
94pub mod client;
95pub mod countries;
96pub mod data;
97pub mod endpoint;
98pub mod errors;
99pub use client::*;
100
101use derive_builder::Builder;
102use serde::Serialize;
103use serde_with::skip_serializing_none;
104
105/// The paypal api endpoint used on a live application.
106pub const LIVE_ENDPOINT: &str = "https://api-m.paypal.com";
107/// The paypal api endpoint used on when testing.
108pub const SANDBOX_ENDPOINT: &str = "https://api-m.sandbox.paypal.com";
109/// Represents the query used in most GET api requests.
110///
111/// Reference: <https://developer.paypal.com/docs/api/reference/api-requests/#query-parameters>
112///
113/// Note: You can avoid most fields by the Default impl like so:
114/// ```
115/// use paypal_rs::Query;
116/// let query = Query { count: Some(40), ..Default::default() };
117/// ```
118#[skip_serializing_none]
119#[derive(Debug, Default, Serialize, Builder, Clone)]
120pub struct Query {
121    /// The number of items to list in the response.
122    pub count: Option<i32>,
123    /// The end date and time for the range to show in the response.
124    pub end_time: Option<chrono::DateTime<chrono::Utc>>,
125    /// The page number indicating which set of items will be returned in the response.
126    /// So, the combination of page=1 and page_size=20 returns the first 20 items.
127    /// The combination of page=2 and page_size=20 returns items 21 through 40.
128    pub page: Option<i32>,
129    /// The number of items to return in the response.
130    pub page_size: Option<i32>,
131    /// Indicates whether to show the total count in the response.
132    pub total_count_required: Option<bool>,
133    /// Sorts the payments in the response by a specified value, such as the create time or update time.
134    pub sort_by: Option<String>,
135    /// Sorts the items in the response in ascending or descending order.
136    pub sort_order: Option<String>,
137    /// The ID of the starting resource in the response.
138    /// When results are paged, you can use the next_id value as the start_id to continue with the next set of results.
139    pub start_id: Option<String>,
140    /// The start index of the payments to list. Typically, you use the start_index to jump to a specific position in the resource history based on its cart.
141    /// For example, to start at the second item in a list of results, specify start_index=2.
142    pub start_index: Option<i32>,
143    /// The start date and time for the range to show in the response.
144    pub start_time: Option<chrono::DateTime<chrono::Utc>>,
145    // TODO: Use https://github.com/samscott89/serde_qs
146}
147
148/// Represents the optional header values used on paypal requests.
149///
150/// <https://developer.paypal.com/docs/api/reference/api-requests/#paypal-auth-assertion>
151#[derive(Debug, Default, Builder, Clone)]
152pub struct HeaderParams {
153    /// The merchant payer id used on PayPal-Auth-Assertion
154    pub merchant_payer_id: Option<String>,
155    /// Verifies that the payment originates from a valid, user-consented device and application.
156    /// Reduces fraud and decreases declines. Transactions that do not include a client metadata ID are not eligible for PayPal Seller Protection.
157    pub client_metadata_id: Option<String>,
158    /// Identifies the caller as a PayPal partner. To receive revenue attribution, specify a unique build notation (BN) code.
159    /// BN codes provide tracking on all transactions that originate or are associated with a particular partner.
160    pub partner_attribution_id: Option<String>,
161    /// Contains a unique user-generated ID that the server stores for a period of time. Use this header to enforce idempotency on REST API POST calls.
162    /// You can make these calls any number of times without concern that the server creates or completes an action on a resource more than once.
163    /// You can retry calls that fail with network timeouts or the HTTP 500 status code. You can retry calls for as long as the server stores the ID.
164    pub request_id: Option<String>,
165    /// The media type. Required for operations with a request body.
166    pub content_type: Option<String>,
167}
168
169#[derive(Debug, Serialize)]
170struct AuthAssertionClaims {
171    pub iss: String,
172    pub payer_id: String,
173}
174
175#[cfg(test)]
176mod tests {
177    use crate::countries::Country;
178    use crate::data::common::Currency;
179    //use crate::Client;
180    //use std::env;
181    use std::str::FromStr;
182
183    /*
184    pub async fn create_client() -> Client {
185        dotenvy::dotenv().ok();
186        let clientid = env::var("PAYPAL_CLIENTID").unwrap();
187        let secret = env::var("PAYPAL_SECRET").unwrap();
188
189        Client::new(clientid, secret, crate::PaypalEnv::Sandbox)
190    }
191    */
192
193    #[test]
194    fn test_currency() {
195        assert_eq!(Currency::EUR.to_string(), "EUR");
196        assert_eq!(Currency::JPY.to_string(), "JPY");
197        assert_eq!(Currency::JPY, Currency::from_str("JPY").unwrap());
198    }
199
200    #[test]
201    fn test_country() {
202        assert_eq!(Country::US.to_string(), "US");
203        assert_eq!(Country::ES.to_string(), "ES");
204        assert_eq!(Country::ES, Country::from_str("ES").unwrap());
205    }
206}