some fixes
This commit is contained in:
parent
89b1fdf113
commit
a4c4838aaf
|
@ -4,7 +4,7 @@
|
|||
//! Customers with a PayPal account can log in and pay the invoice with PayPal. Alternatively,
|
||||
//! customers can pay as a guest with a debit card or credit card. For more information, see the Invoicing Overview and the Invoicing Integration Guide.
|
||||
//!
|
||||
//! Reference: https://developer.paypal.com/docs/api/invoicing/v2/
|
||||
//! Reference: <https://developer.paypal.com/docs/api/invoicing/v2/>
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
|
@ -53,8 +53,8 @@ impl Endpoint for GenerateInvoiceNumber {
|
|||
reqwest::Method::POST
|
||||
}
|
||||
|
||||
fn body(&self) -> Option<&Self::Body> {
|
||||
Some(&self.invoice_number)
|
||||
fn body(&self) -> Option<Self::Body> {
|
||||
Some(self.invoice_number.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,8 +88,8 @@ impl Endpoint for CreateDraftInvoice {
|
|||
reqwest::Method::POST
|
||||
}
|
||||
|
||||
fn body(&self) -> Option<&Self::Body> {
|
||||
Some(&self.invoice)
|
||||
fn body(&self) -> Option<Self::Body> {
|
||||
Some(self.invoice.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,8 +153,8 @@ impl Endpoint for ListInvoices {
|
|||
reqwest::Method::GET
|
||||
}
|
||||
|
||||
fn query(&self) -> Option<&Self::Query> {
|
||||
Some(&self.query)
|
||||
fn query(&self) -> Option<Self::Query> {
|
||||
Some(self.query.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,12 +234,12 @@ impl Endpoint for UpdateInvoice {
|
|||
reqwest::Method::PUT
|
||||
}
|
||||
|
||||
fn body(&self) -> Option<&Self::Body> {
|
||||
Some(&self.invoice)
|
||||
fn body(&self) -> Option<Self::Body> {
|
||||
Some(self.invoice.clone())
|
||||
}
|
||||
|
||||
fn query(&self) -> Option<&Self::Query> {
|
||||
Some(&self.query)
|
||||
fn query(&self) -> Option<Self::Query> {
|
||||
Some(self.query.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,8 +274,8 @@ impl Endpoint for CancelInvoice {
|
|||
reqwest::Method::POST
|
||||
}
|
||||
|
||||
fn body(&self) -> Option<&Self::Body> {
|
||||
Some(&self.reason)
|
||||
fn body(&self) -> Option<Self::Body> {
|
||||
Some(self.reason.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -383,7 +383,7 @@ mod tests {
|
|||
|
||||
let invoice = CreateDraftInvoice::new(payload);
|
||||
|
||||
let res = client.execute(&invoice).await?;
|
||||
let _res = client.execute(&invoice).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! An order represents a payment between two or more parties. Use the Orders API to create, update, retrieve, authorize, and capture orders.
|
||||
//!
|
||||
//! https://developer.paypal.com/docs/api/orders/v2/
|
||||
//! <https://developer.paypal.com/docs/api/orders/v2/>
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
|
@ -41,8 +41,8 @@ impl Endpoint for CreateOrder {
|
|||
reqwest::Method::POST
|
||||
}
|
||||
|
||||
fn body(&self) -> Option<&Self::Body> {
|
||||
Some(&self.order)
|
||||
fn body(&self) -> Option<Self::Body> {
|
||||
Some(self.order.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,10 +97,11 @@ pub struct PaymentSource {
|
|||
}
|
||||
|
||||
/// The capture order endpoint body.
|
||||
#[derive(Debug, Serialize, Clone)]
|
||||
#[derive(Debug, Serialize, Clone, Default)]
|
||||
pub struct PaymentSourceBody {
|
||||
/// The payment source definition.
|
||||
pub payment_source: PaymentSource,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub payment_source: Option<PaymentSource>,
|
||||
}
|
||||
|
||||
/// Captures payment for an order. To successfully capture payment for an order,
|
||||
|
@ -111,7 +112,7 @@ pub struct CaptureOrder {
|
|||
/// The id of the order.
|
||||
pub order_id: String,
|
||||
/// The endpoint body.
|
||||
pub body: Option<PaymentSourceBody>,
|
||||
pub body: PaymentSourceBody,
|
||||
}
|
||||
|
||||
impl CaptureOrder {
|
||||
|
@ -119,7 +120,7 @@ impl CaptureOrder {
|
|||
pub fn new(order_id: &str) -> Self {
|
||||
Self {
|
||||
order_id: order_id.to_string(),
|
||||
body: None,
|
||||
body: PaymentSourceBody::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,8 +140,8 @@ impl Endpoint for CaptureOrder {
|
|||
reqwest::Method::POST
|
||||
}
|
||||
|
||||
fn body(&self) -> Option<&Self::Body> {
|
||||
self.body.as_ref()
|
||||
fn body(&self) -> Option<Self::Body> {
|
||||
Some(self.body.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,7 +153,7 @@ pub struct AuthorizeOrder {
|
|||
/// The order id.
|
||||
order_id: String,
|
||||
/// The endpoint body.
|
||||
pub body: Option<PaymentSourceBody>,
|
||||
pub body: PaymentSourceBody,
|
||||
}
|
||||
|
||||
impl AuthorizeOrder {
|
||||
|
@ -160,7 +161,7 @@ impl AuthorizeOrder {
|
|||
pub fn new(order_id: &str) -> Self {
|
||||
Self {
|
||||
order_id: order_id.to_string(),
|
||||
body: None,
|
||||
body: PaymentSourceBody::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -180,8 +181,8 @@ impl Endpoint for AuthorizeOrder {
|
|||
reqwest::Method::POST
|
||||
}
|
||||
|
||||
fn body(&self) -> Option<&Self::Body> {
|
||||
self.body.as_ref()
|
||||
fn body(&self) -> Option<Self::Body> {
|
||||
Some(self.body.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,7 +195,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn test_order() -> anyhow::Result<()> {
|
||||
let mut client = create_client().await;
|
||||
client.get_access_token().await?;
|
||||
client.get_access_token().await.expect("get access token error");
|
||||
|
||||
let order = OrderPayloadBuilder::default()
|
||||
.intent(Intent::Authorize)
|
||||
|
@ -219,7 +220,11 @@ mod tests {
|
|||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
.await;
|
||||
|
||||
assert!(order_created.is_ok());
|
||||
|
||||
let order_created = order_created?;
|
||||
|
||||
assert_ne!(order_created.id, "");
|
||||
assert_eq!(order_created.status, OrderStatus::Created);
|
||||
|
@ -235,14 +240,19 @@ mod tests {
|
|||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
.await;
|
||||
|
||||
assert!(show_order_result.is_ok());
|
||||
|
||||
let show_order_result = show_order_result?;
|
||||
|
||||
assert_eq!(order_created.id, show_order_result.id);
|
||||
assert_eq!(order_created.status, show_order_result.status);
|
||||
|
||||
let capture_order = CaptureOrder::new(&show_order_result.id);
|
||||
let authorize_order = AuthorizeOrder::new(&show_order_result.id);
|
||||
|
||||
let _res = client.execute(&capture_order).await?;
|
||||
let res = client.execute(&authorize_order).await;
|
||||
assert!(res.is_err()); // Fails with ORDER_NOT_APPROVED
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Call the Payments API to authorize payments, capture authorized payments, refund payments that have already been captured, and show payment information.
|
||||
//!
|
||||
//! Reference: https://developer.paypal.com/docs/api/payments/v2/
|
||||
//! Reference: <https://developer.paypal.com/docs/api/payments/v2/>
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
|
@ -42,8 +42,4 @@ impl Endpoint for GetAuthorizedPayment {
|
|||
fn method(&self) -> reqwest::Method {
|
||||
reqwest::Method::GET
|
||||
}
|
||||
|
||||
fn body(&self) -> Option<&Self::Body> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use crate::{
|
|||
|
||||
/// Represents the access token returned by the OAuth2 authentication.
|
||||
///
|
||||
/// https://developer.paypal.com/docs/api/get-an-access-token-postman/
|
||||
/// <https://developer.paypal.com/docs/api/get-an-access-token-postman/>
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct AccessToken {
|
||||
/// The OAuth2 scopes.
|
||||
|
@ -196,7 +196,7 @@ impl Client {
|
|||
let mut url = endpoint.full_path(self.sandbox);
|
||||
|
||||
if let Some(query) = endpoint.query() {
|
||||
let query_string = serde_qs::to_string(query).expect("serialize the query correctly");
|
||||
let query_string = serde_qs::to_string(&query).expect("serialize the query correctly");
|
||||
url.push_str(&query_string);
|
||||
}
|
||||
|
||||
|
@ -204,7 +204,7 @@ impl Client {
|
|||
request = self.setup_headers(request, headers).await?;
|
||||
|
||||
if let Some(body) = endpoint.body() {
|
||||
request = request.json(body);
|
||||
request = request.json(&body);
|
||||
}
|
||||
|
||||
let res = request.send().await?;
|
||||
|
@ -225,7 +225,7 @@ 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.
|
||||
/// You must remember to call [Client::get_access_token] first or this may fail due to not being authed.
|
||||
pub async fn execute<E>(&self, endpoint: &E) -> Result<E::Response, ResponseError>
|
||||
where
|
||||
E: Endpoint,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//! Generated using https://github.com/edg-l/payhelper
|
||||
//! Generated using <https://github.com/edg-l/payhelper>
|
||||
|
||||
use crate::errors::InvalidCountryError;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::str::FromStr;
|
|||
|
||||
/// The phone type.
|
||||
///
|
||||
/// https://developer.paypal.com/docs/api/orders/v2/#definition-phone_with_type
|
||||
/// <https://developer.paypal.com/docs/api/orders/v2/#definition-phone_with_type>
|
||||
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Copy, Clone)]
|
||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||
#[allow(missing_docs)]
|
||||
|
|
|
@ -569,7 +569,7 @@ pub struct InvoicePayload {
|
|||
pub refunds: Option<Refunds>,
|
||||
}
|
||||
|
||||
/// Definition: https://developer.paypal.com/docs/api/invoicing/v2/#invoices_get
|
||||
/// Definition: <https://developer.paypal.com/docs/api/invoicing/v2/#invoices_get>
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Builder)]
|
||||
#[builder(setter(strip_option, into))]
|
||||
|
|
|
@ -27,7 +27,7 @@ impl Default for Intent {
|
|||
|
||||
/// Represents a payer name.
|
||||
///
|
||||
/// https://developer.paypal.com/docs/api/orders/v2/#definition-payer.name
|
||||
/// <https://developer.paypal.com/docs/api/orders/v2/#definition-payer.name>
|
||||
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
|
||||
pub struct PayerName {
|
||||
/// When the party is a person, the party's given, or first, name.
|
||||
|
@ -80,7 +80,7 @@ pub struct TaxInfo {
|
|||
|
||||
/// The customer who approves and pays for the order. The customer is also known as the payer.
|
||||
///
|
||||
/// https://developer.paypal.com/docs/api/orders/v2/#definition-payer
|
||||
/// <https://developer.paypal.com/docs/api/orders/v2/#definition-payer>
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Default, Serialize, Deserialize, Clone, Builder)]
|
||||
pub struct Payer {
|
||||
|
@ -428,7 +428,7 @@ pub struct PurchaseUnit {
|
|||
pub id: Option<String>,
|
||||
/// The soft descriptor is the dynamic text used to construct the statement descriptor that appears on a payer's card statement.
|
||||
///
|
||||
/// More info here: https://developer.paypal.com/docs/api/orders/v2/#definition-purchase_unit_request
|
||||
/// More info here: <https://developer.paypal.com/docs/api/orders/v2/#definition-purchase_unit_request>
|
||||
pub soft_descriptor: Option<String>,
|
||||
/// An array of items that the customer purchases from the merchant.
|
||||
pub items: Option<Vec<Item>>,
|
||||
|
|
|
@ -20,12 +20,12 @@ pub trait Endpoint {
|
|||
fn method(&self) -> reqwest::Method;
|
||||
|
||||
/// The query to be used when calling this endpoint.
|
||||
fn query(&self) -> Option<&Self::Query> {
|
||||
fn query(&self) -> Option<Self::Query> {
|
||||
None
|
||||
}
|
||||
|
||||
/// The body to be used when calling this endpoint.
|
||||
fn body(&self) -> Option<&Self::Body> {
|
||||
fn body(&self) -> Option<Self::Body> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -33,10 +33,14 @@ pub trait Endpoint {
|
|||
///
|
||||
/// Automatically implemented.
|
||||
fn full_path(&self, is_sandbox: bool) -> String {
|
||||
let relative_path = self.relative_path();
|
||||
|
||||
assert!(relative_path.starts_with('/'), "relative path must start with '/'");
|
||||
|
||||
if is_sandbox {
|
||||
format!("{}{}", SANDBOX_ENDPOINT, self.relative_path())
|
||||
format!("{}{}", SANDBOX_ENDPOINT, relative_path)
|
||||
} else {
|
||||
format!("{}{}", LIVE_ENDPOINT, self.relative_path())
|
||||
format!("{}{}", LIVE_ENDPOINT, relative_path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
//!
|
||||
//! A rust library that wraps the [paypal api](https://developer.paypal.com/docs/api) asynchronously in a strongly typed manner.
|
||||
//!
|
||||
//! 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)
|
||||
//!
|
||||
//! Currently in early development.
|
||||
//!
|
||||
|
||||
|
@ -91,7 +93,7 @@ pub const LIVE_ENDPOINT: &str = "https://api-m.paypal.com";
|
|||
pub const SANDBOX_ENDPOINT: &str = "https://api-m.sandbox.paypal.com";
|
||||
/// Represents the query used in most GET api requests.
|
||||
///
|
||||
/// Reference: https://developer.paypal.com/docs/api/reference/api-requests/#query-parameters
|
||||
/// Reference: <https://developer.paypal.com/docs/api/reference/api-requests/#query-parameters>
|
||||
///
|
||||
/// Note: You can avoid most fields by the Default impl like so:
|
||||
/// ```
|
||||
|
@ -130,7 +132,7 @@ pub struct Query {
|
|||
|
||||
/// Represents the optional header values used on paypal requests.
|
||||
///
|
||||
/// https://developer.paypal.com/docs/api/reference/api-requests/#paypal-auth-assertion
|
||||
/// <https://developer.paypal.com/docs/api/reference/api-requests/#paypal-auth-assertion>
|
||||
#[derive(Debug, Default, Builder, Clone)]
|
||||
pub struct HeaderParams {
|
||||
/// The merchant payer id used on PayPal-Auth-Assertion
|
||||
|
|
Loading…
Reference in a new issue