add record_invoice_payment

This commit is contained in:
Edgar 2020-10-14 12:49:43 +02:00
parent 3932847903
commit 84f1261b62
No known key found for this signature in database
GPG key ID: 8731E6C0166EAA85
2 changed files with 60 additions and 17 deletions

View file

@ -1,7 +1,6 @@
//! Common paypal object definitions used amon 2 or more APIs //! Common paypal object definitions used amon 2 or more APIs
use serde::{Serialize, Deserialize}; use serde::{Deserialize, Serialize};
/// The phone type. /// The phone type.
/// ///
@ -20,23 +19,23 @@ pub enum PhoneType {
/// The non-portable additional address details /// The non-portable additional address details
#[derive(Debug, Default, Serialize, Deserialize)] #[derive(Debug, Default, Serialize, Deserialize)]
pub struct AddressDetails { pub struct AddressDetails {
/// The street number. /// The street number.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub street_number: Option<String>, pub street_number: Option<String>,
/// The street name. Just Drury in Drury Lane. /// The street name. Just Drury in Drury Lane.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub street_name: Option<String>, pub street_name: Option<String>,
/// The street type. For example, avenue, boulevard, road, or expressway. /// The street type. For example, avenue, boulevard, road, or expressway.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub street_type: Option<String>, pub street_type: Option<String>,
/// The delivery service. Post office box, bag number, or post office name. /// The delivery service. Post office box, bag number, or post office name.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub delivery_service: Option<String>, pub delivery_service: Option<String>,
/// A named locations that represents the premise. Usually a building name or number or collection of buildings with a common name or number. For example, Craven House. /// A named locations that represents the premise. Usually a building name or number or collection of buildings with a common name or number. For example, Craven House.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub building_name: Option<String>, pub building_name: Option<String>,
/// The first-order entity below a named building or location that represents the sub-premise. /// The first-order entity below a named building or location that represents the sub-premise.
/// Usually a single building within a collection of buildings with a common name. Can be a flat, story, floor, room, or apartment. /// Usually a single building within a collection of buildings with a common name. Can be a flat, story, floor, room, or apartment.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub sub_building: Option<String>, pub sub_building: Option<String>,
} }
@ -105,4 +104,5 @@ pub struct LinkDescription {
/// The HTTP method required to make the related call. /// The HTTP method required to make the related call.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub method: Option<LinkMethod>, pub method: Option<LinkMethod>,
} }

View file

@ -471,6 +471,12 @@ pub enum PaymentMethod {
Other, Other,
} }
impl Default for PaymentMethod {
fn default() -> Self {
PaymentMethod::Paypal
}
}
/// Payment detail /// Payment detail
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct PaymentDetail { pub struct PaymentDetail {
@ -697,6 +703,20 @@ pub struct QRCodeParams {
pub action: Option<String>, pub action: Option<String>,
} }
#[derive(Debug, Serialize, Deserialize, Default)]
pub struct RecordPaymentPayload {
#[serde(skip_serializing_if = "Option::is_none")]
payment_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
payment_date: Option<chrono::DateTime<chrono::Utc>>,
method: PaymentMethod,
#[serde(skip_serializing_if = "Option::is_none")]
note: Option<String>,
amount: Amount,
#[serde(skip_serializing_if = "Option::is_none")]
shipping_info: Option<ContactInformation>,
}
impl super::Client { impl super::Client {
/// Generates the next invoice number that is available to the merchant. /// Generates the next invoice number that is available to the merchant.
/// ///
@ -727,8 +747,8 @@ impl super::Client {
/// Include invoice details including merchant information. The invoice object must include an items array. /// Include invoice details including merchant information. The invoice object must include an items array.
pub async fn create_draft_invoice( pub async fn create_draft_invoice(
&self, &self,
header_params: crate::HeaderParams,
invoice: InvoicePayload, invoice: InvoicePayload,
header_params: crate::HeaderParams,
) -> Result<Invoice, Box<dyn std::error::Error>> { ) -> Result<Invoice, Box<dyn std::error::Error>> {
let build = self.setup_headers( let build = self.setup_headers(
self.client self.client
@ -749,8 +769,8 @@ impl super::Client {
/// Get an invoice by ID. /// Get an invoice by ID.
pub async fn get_invoice<S: std::fmt::Display>( pub async fn get_invoice<S: std::fmt::Display>(
&self, &self,
header_params: crate::HeaderParams,
invoice_id: S, invoice_id: S,
header_params: crate::HeaderParams,
) -> Result<Invoice, Box<dyn std::error::Error>> { ) -> Result<Invoice, Box<dyn std::error::Error>> {
let build = self.setup_headers( let build = self.setup_headers(
self.client self.client
@ -772,9 +792,9 @@ impl super::Client {
/// Page size has the following limits: [1, 100]. /// Page size has the following limits: [1, 100].
pub async fn list_invoices( pub async fn list_invoices(
&self, &self,
header_params: crate::HeaderParams,
page: i32, page: i32,
page_size: i32, page_size: i32,
header_params: crate::HeaderParams,
) -> Result<InvoiceList, Box<dyn std::error::Error>> { ) -> Result<InvoiceList, Box<dyn std::error::Error>> {
let build = self.setup_headers( let build = self.setup_headers(
self.client.get( self.client.get(
@ -802,8 +822,8 @@ impl super::Client {
/// Delete a invoice /// Delete a invoice
pub async fn delete_invoice<S: std::fmt::Display>( pub async fn delete_invoice<S: std::fmt::Display>(
&self, &self,
header_params: crate::HeaderParams,
invoice_id: S, invoice_id: S,
header_params: crate::HeaderParams,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
let build = self.setup_headers( let build = self.setup_headers(
self.client self.client
@ -823,10 +843,10 @@ impl super::Client {
/// Update a invoice /// Update a invoice
pub async fn update_invoice( pub async fn update_invoice(
&self, &self,
header_params: crate::HeaderParams,
invoice: Invoice, invoice: Invoice,
send_to_recipient: bool, send_to_recipient: bool,
send_to_invoicer: bool, send_to_invoicer: bool,
header_params: crate::HeaderParams,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
let build = self.setup_headers( let build = self.setup_headers(
self.client.put( self.client.put(
@ -854,9 +874,9 @@ impl super::Client {
/// Cancel a invoice /// Cancel a invoice
pub async fn cancel_invoice<S: std::fmt::Display>( pub async fn cancel_invoice<S: std::fmt::Display>(
&self, &self,
header_params: crate::HeaderParams,
invoice_id: S, invoice_id: S,
reason: CancelReason, reason: CancelReason,
header_params: crate::HeaderParams,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
let build = self.setup_headers( let build = self.setup_headers(
self.client self.client
@ -876,9 +896,9 @@ impl super::Client {
/// Generate a QR code /// Generate a QR code
pub async fn generate_qr_code<S: std::fmt::Display>( pub async fn generate_qr_code<S: std::fmt::Display>(
&self, &self,
header_params: crate::HeaderParams,
invoice_id: S, invoice_id: S,
params: QRCodeParams, params: QRCodeParams,
header_params: crate::HeaderParams,
) -> Result<Bytes, Box<dyn std::error::Error>> { ) -> Result<Bytes, Box<dyn std::error::Error>> {
let build = self.setup_headers( let build = self.setup_headers(
self.client self.client
@ -896,5 +916,28 @@ impl super::Client {
} }
} }
// TODO: https://developer.paypal.com/docs/api/invoicing/v2/#invoices_payments /// Records a payment for the invoice. If no payment is due, the invoice is marked as PAID. Otherwise, the invoice is marked as PARTIALLY PAID.
pub async fn record_invoice_payment<S: std::fmt::Display>(
&self,
invoice_id: S,
payload: RecordPaymentPayload,
header_params: crate::HeaderParams,
) -> Result<String, Box<dyn std::error::Error>> {
let build = self.setup_headers(
self.client
.post(format!("{}/v2/invoicing/invoices/{}/payments", self.endpoint(), invoice_id).as_str()),
header_params,
);
let res = build.json(&payload).send().await?;
if res.status().is_success() {
let x = res.json::<HashMap<String, String>>().await?;
Ok(x.get("payment_id").unwrap().to_owned())
} else {
Err(Box::new(res.json::<errors::ApiResponseError>().await?))
}
}
// TODO: https://developer.paypal.com/docs/api/invoicing/v2/#invoices_payments-delete
} }