#177 feature/Invoice: init, added Invoice related structs, implemented met… (#249)

* feature/Invoice: init, added Invoice related structs, implemented methods:GenerateInvoiceNumber,GetInvoiceDetails(by ID)

* feature/Invoice: added implemented endpoints to README along with Usage

Co-authored-by: Akshay Prabhakant <akshayprabhakant@Akshays-MacBook-Pro.local>
This commit is contained in:
Akshay Prabhakant 2022-10-28 12:50:28 +05:30 committed by GitHub
parent 1bb626d559
commit 4c16ffad0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 728 additions and 0 deletions

View File

@ -101,6 +101,11 @@
* POST /v1/billing/subscriptions/:id/capture
* POST /v1/billing/subscriptions/:id/suspend
* GET /v1/billing/subscriptions/:id/transactions
### Invoicing
* POST /v2/invoicing/generate-next-invoice-number
* GET /v2/invoicing/invoices/:id
## Missing endpoints
@ -371,6 +376,27 @@ c.DeleteWebhook("WebhookID")
c.ListWebhooks(paypal.AncorTypeApplication)
```
### Generate Next Invoice Number
```go
// GenerateInvoiceNumber: generates the next invoice number that is available to the merchant.
c.GenerateInvoiceNumber(ctx) // might return something like "0001" or "0010".
```
### Get Invoice Details by ID
```go
// the second argument is an ID, it should be valid
invoice, err := c.GetInvoiceDetails(ctx, "INV2-XFXV-YW42-ZANU-4F33")
```
* for now, we are yet to implement the ShowAllInvoices endpoint, so use the following cURL request for the same(this gives you the list of invoice-IDs for this customer)
```bash
curl -v -X GET https://api-m.sandbox.paypal.com/v2/invoicing/invoices?total_required=true \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <Token>"
```
* refer to the beginning of this Usage section for obtaining a Token.
## How to Contribute
* Fork a repository

38
invoicing.go Normal file
View File

@ -0,0 +1,38 @@
package paypal
import (
"context"
"fmt"
)
// GenerateInvoiceNumber: generates the next invoice number that is available to the merchant.
// Endpoint: POST /v2/invoicing/generate-next-invoice-number
func (c *Client) GenerateInvoiceNumber(ctx context.Context) (*InvoiceNumber, error) {
req, err := c.NewRequest(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/invoicing/generate-next-invoice-number"), nil)
nextInvoiceNumber := &InvoiceNumber{}
if err != nil {
return nextInvoiceNumber, err
}
if err = c.SendWithAuth(req, nextInvoiceNumber); err != nil {
return nextInvoiceNumber, err
}
return nextInvoiceNumber, nil
}
// GetInvoiceDetails: show invoice details for a particular invoice by ID.
// Endpoint: GET /v2/invoicing/invoices/{invoice_id}
func (c *Client) GetInvoiceDetails(ctx context.Context, invoiceID string) (*Invoice, error) {
req, err := c.NewRequest(ctx, "GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v2/invoicing/invoices/", invoiceID), nil)
invoice := &Invoice{}
if err != nil {
return invoice, err
}
if err = c.SendWithAuth(req, invoice); err != nil {
return invoice, err
}
return invoice, nil
}

406
invoicing_test.go Normal file
View File

@ -0,0 +1,406 @@
package paypal_test
import (
"context"
"encoding/json"
"testing"
"github.com/plutov/paypal/v4"
"github.com/stretchr/testify/assert"
)
// All test values are defined here
var devTestClientID = "AXy9orp-CDaHhBZ9C78QHW2BKZpACgroqo85_NIOa9mIfJ9QnSVKzY-X_rivR_fTUUr6aLjcJsj6sDur"
var devTestSecret = "EBoIiUSkCKeSk49hHSgTem1qnjzzJgRQHDEHvGpzlLEf_nIoJd91xu8rPOBDCdR_UYNKVxJE-UgS2iCw"
var devAPIBaseSandBox = "https://api.sandbox.paypal.com"
func TestGenerateInvoiceNumber(t *testing.T) {
ctx := context.Background()
c, _ := paypal.NewClient(devTestClientID, devTestSecret, devAPIBaseSandBox)
_, err := c.GetAccessToken(ctx)
assert.Equal(t, nil, err)
_, err = c.GenerateInvoiceNumber(ctx)
assert.Equal(t, nil, err)
}
func assertTwoInvoices(t *testing.T, invoice paypal.Invoice, testInvoice paypal.Invoice) {
// additional_recipients
assert.Equal(t, len(invoice.AdditionalRecipients), len(testInvoice.AdditionalRecipients))
// additional_recipients --> email_address !! EQUALITY OF SPLICE OF STRUCT REMAINING !!
// amount
assert.Equal(t, invoice.AmountSummary.Currency, testInvoice.AmountSummary.Currency)
assert.Equal(t, invoice.AmountSummary.Value, testInvoice.AmountSummary.Value)
// amount-->breakdown-->custom-->amount
assert.Equal(t, invoice.AmountSummary.Breakdown.Custom.Amount.Currency, testInvoice.AmountSummary.Breakdown.Custom.Amount.Currency)
assert.Equal(t, invoice.AmountSummary.Breakdown.Custom.Amount.Value, testInvoice.AmountSummary.Breakdown.Custom.Amount.Value)
// amount-->breakdown-->custom-->label
assert.Equal(t, invoice.AmountSummary.Breakdown.Custom.Label, testInvoice.AmountSummary.Breakdown.Custom.Label)
// amount-->breakdown-->discount-->amount
assert.Equal(t, invoice.AmountSummary.Breakdown.Discount.InvoiceDiscount.DiscountAmount.Currency, testInvoice.AmountSummary.Breakdown.Discount.InvoiceDiscount.DiscountAmount.Currency)
assert.Equal(t, invoice.AmountSummary.Breakdown.Discount.InvoiceDiscount.DiscountAmount.Value, testInvoice.AmountSummary.Breakdown.Discount.InvoiceDiscount.DiscountAmount.Value)
// amount-->breakdown-->discount-->percent
assert.Equal(t, invoice.AmountSummary.Breakdown.Discount.InvoiceDiscount.Percent, testInvoice.AmountSummary.Breakdown.Discount.InvoiceDiscount.Percent)
// amount-->breakdown-->discount-->item_discount
assert.Equal(t, invoice.AmountSummary.Breakdown.Discount.ItemDiscount.Currency, testInvoice.AmountSummary.Breakdown.Discount.ItemDiscount.Currency)
assert.Equal(t, invoice.AmountSummary.Breakdown.Discount.ItemDiscount.Value, testInvoice.AmountSummary.Breakdown.Discount.ItemDiscount.Value)
// amount-->breakdown-->item_total
assert.Equal(t, invoice.AmountSummary.Breakdown.ItemTotal.Currency, testInvoice.AmountSummary.Breakdown.ItemTotal.Currency)
assert.Equal(t, invoice.AmountSummary.Breakdown.ItemTotal.Value, testInvoice.AmountSummary.Breakdown.ItemTotal.Value)
// amount-->breakdown-->shipping-->amount
assert.Equal(t, invoice.AmountSummary.Breakdown.Shipping.Amount.Currency, testInvoice.AmountSummary.Breakdown.Shipping.Amount.Currency)
assert.Equal(t, invoice.AmountSummary.Breakdown.Shipping.Amount.Value, testInvoice.AmountSummary.Breakdown.Shipping.Amount.Value)
// amount-->breakdown-->shipping-->tax
assert.Equal(t, invoice.AmountSummary.Breakdown.Shipping.Tax.Amount.Currency, testInvoice.AmountSummary.Breakdown.Shipping.Tax.Amount.Currency)
assert.Equal(t, invoice.AmountSummary.Breakdown.Shipping.Tax.Amount.Value, testInvoice.AmountSummary.Breakdown.Shipping.Tax.Amount.Value)
assert.Equal(t, invoice.AmountSummary.Breakdown.Shipping.Tax.ID, testInvoice.AmountSummary.Breakdown.Shipping.Tax.ID)
assert.Equal(t, invoice.AmountSummary.Breakdown.Shipping.Tax.Name, testInvoice.AmountSummary.Breakdown.Shipping.Tax.Name)
assert.Equal(t, invoice.AmountSummary.Breakdown.Shipping.Tax.Percent, testInvoice.AmountSummary.Breakdown.Shipping.Tax.Percent)
// amount-->breakdown-->tax_total
assert.Equal(t, invoice.AmountSummary.Breakdown.TaxTotal.Currency, testInvoice.AmountSummary.Breakdown.TaxTotal.Currency)
assert.Equal(t, invoice.AmountSummary.Breakdown.TaxTotal.Value, testInvoice.AmountSummary.Breakdown.TaxTotal.Value)
// configuration
assert.Equal(t, invoice.Configuration.AllowTip, testInvoice.Configuration.AllowTip)
assert.Equal(t, invoice.Configuration.TaxCalculatedAfterDiscount, testInvoice.Configuration.TaxCalculatedAfterDiscount)
assert.Equal(t, invoice.Configuration.TaxInclusive, testInvoice.Configuration.TaxInclusive)
assert.Equal(t, invoice.Configuration.TemplateId, testInvoice.Configuration.TemplateId)
// configuration --> partial_payment
assert.Equal(t, invoice.Configuration.PartialPayment.AllowPartialPayment, testInvoice.Configuration.PartialPayment.AllowPartialPayment)
assert.Equal(t, invoice.Configuration.PartialPayment.MinimumAmountDue.Currency, testInvoice.Configuration.PartialPayment.MinimumAmountDue.Currency)
assert.Equal(t, invoice.Configuration.PartialPayment.MinimumAmountDue.Value, testInvoice.Configuration.PartialPayment.MinimumAmountDue.Value)
// detail
assert.Equal(t, invoice.Detail.CurrencyCode, testInvoice.Detail.CurrencyCode)
assert.Equal(t, invoice.Detail.InvoiceDate, testInvoice.Detail.InvoiceDate)
assert.Equal(t, invoice.Detail.InvoiceNumber, testInvoice.Detail.InvoiceNumber)
assert.Equal(t, invoice.Detail.Memo, testInvoice.Detail.Memo)
assert.Equal(t, invoice.Detail.Note, testInvoice.Detail.Note)
assert.Equal(t, invoice.Detail.Reference, testInvoice.Detail.Reference)
assert.Equal(t, invoice.Detail.TermsAndConditions, testInvoice.Detail.TermsAndConditions)
// detail --> attachments !! EQUALITY OF SPLICE OF STRUCT REMAINING !!
assert.Equal(t, len(invoice.Detail.Attachments), len(testInvoice.Detail.Attachments))
// detail --> metadata
assert.Equal(t, invoice.Detail.Metadata.CancelTime, testInvoice.Detail.Metadata.CancelTime)
assert.Equal(t, invoice.Detail.Metadata.CancellledTimeBy, testInvoice.Detail.Metadata.CancellledTimeBy)
assert.Equal(t, invoice.Detail.Metadata.CreateTime, testInvoice.Detail.Metadata.CreateTime)
assert.Equal(t, invoice.Detail.Metadata.CreatedBy, testInvoice.Detail.Metadata.CreatedBy)
assert.Equal(t, invoice.Detail.Metadata.CreatedByFlow, testInvoice.Detail.Metadata.CreatedByFlow)
assert.Equal(t, invoice.Detail.Metadata.FirstSentTime, testInvoice.Detail.Metadata.FirstSentTime)
assert.Equal(t, invoice.Detail.Metadata.InvoicerViewUrl, testInvoice.Detail.Metadata.InvoicerViewUrl)
assert.Equal(t, invoice.Detail.Metadata.LastSentBy, testInvoice.Detail.Metadata.LastSentBy)
assert.Equal(t, invoice.Detail.Metadata.LastSentTime, testInvoice.Detail.Metadata.LastSentTime)
assert.Equal(t, invoice.Detail.Metadata.LastUpdateTime, testInvoice.Detail.Metadata.LastUpdateTime)
assert.Equal(t, invoice.Detail.Metadata.LastUpdatedBy, testInvoice.Detail.Metadata.LastUpdatedBy)
assert.Equal(t, invoice.Detail.Metadata.RecipientViewUrl, testInvoice.Detail.Metadata.RecipientViewUrl)
// detail --> payment_term
assert.Equal(t, invoice.Detail.PaymentTerm.DueDate, testInvoice.Detail.PaymentTerm.DueDate)
assert.Equal(t, invoice.Detail.PaymentTerm.TermType, testInvoice.Detail.PaymentTerm.TermType)
// due_amount
assert.Equal(t, invoice.DueAmount.Currency, testInvoice.DueAmount.Currency)
assert.Equal(t, invoice.DueAmount.Value, testInvoice.DueAmount.Value)
// gratuity
assert.Equal(t, invoice.Gratuity.Currency, testInvoice.Gratuity.Currency)
assert.Equal(t, invoice.Gratuity.Value, testInvoice.Gratuity.Value)
// id
assert.Equal(t, invoice.ID, testInvoice.ID)
// invoicer
assert.Equal(t, invoice.Invoicer.AdditionalNotes, testInvoice.Invoicer.AdditionalNotes)
assert.Equal(t, invoice.Invoicer.EmailAddress, testInvoice.Invoicer.EmailAddress)
assert.Equal(t, invoice.Invoicer.LogoUrl, testInvoice.Invoicer.LogoUrl)
assert.Equal(t, invoice.Invoicer.TaxId, testInvoice.Invoicer.TaxId)
assert.Equal(t, invoice.Invoicer.Website, testInvoice.Invoicer.Website)
// !!! SPLICE EQUALITY STILL REMAINING !!!!!
// invoicer --> phones
assert.Equal(t, len(invoice.Invoicer.Phones), len(testInvoice.Invoicer.Phones))
// items
// !!! SPLICE EQUALITY STILL REMAINING !!!!!
assert.Equal(t, len(invoice.Items), len(testInvoice.Items))
// links
// !!! SPLICE EQUALITY STILL REMAINING !!!!!
assert.Equal(t, len(invoice.Links), len(testInvoice.Links))
// parent_id
assert.Equal(t, invoice.ParentID, testInvoice.ParentID)
// payments
assert.Equal(t, invoice.Payments.PaidAmount.Currency, testInvoice.Payments.PaidAmount.Currency)
assert.Equal(t, invoice.Payments.PaidAmount.Value, testInvoice.Payments.PaidAmount.Value)
// payments --> transactions
assert.Equal(t, len(invoice.Payments.Transactions), len(testInvoice.Payments.Transactions))
// primary_recipients
// !!! SPLICE EQUALITY STILL REMAINING !!!!!
assert.Equal(t, len(invoice.PrimaryRecipients), len(testInvoice.PrimaryRecipients))
// refunds
assert.Equal(t, invoice.Refunds.RefundAmount.Currency, testInvoice.Refunds.RefundAmount.Currency)
assert.Equal(t, invoice.Refunds.RefundAmount.Value, testInvoice.Refunds.RefundAmount.Value)
assert.Equal(t, len(invoice.Refunds.RefundDetails), len(testInvoice.Refunds.RefundDetails))
// status
assert.Equal(t, invoice.Status, testInvoice.Status)
}
func TestGetInvoice(t *testing.T) {
testInvoiceJSONData := []byte(`
{
"amount": {
"breakdown": {
"custom": {
"amount": {
"currency_code": "USD",
"value": "10.00"
},
"label": "Packing Charges"
},
"discount": {
"invoice_discount": {
"amount": {
"currency_code": "USD",
"value": "-2.63"
},
"percent": "5"
},
"item_discount": {
"currency_code": "USD",
"value": "-7.50"
}
},
"item_total": {
"currency_code": "USD",
"value": "60.00"
},
"shipping": {
"amount": {
"currency_code": "USD",
"value": "10.00"
},
"tax": {
"amount": {
"currency_code": "USD",
"value": "0.73"
},
"id": "TAX-9AU06895VD287170A",
"name": "Sales Tax",
"percent": "7.25"
}
},
"tax_total": {
"currency_code": "USD",
"value": "4.34"
}
},
"currency_code": "USD",
"value": "74.21"
},
"configuration": {
"allow_tip": true,
"partial_payment": {
"allow_partial_payment": true,
"minimum_amount_due": {
"currency_code": "USD",
"value": "20.00"
}
},
"tax_calculated_after_discount": true,
"tax_inclusive": false,
"template_id": "TEMP-4NW98229SC0703920"
},
"detail": {
"additional_data": "2-4",
"archived": false,
"category_code": "SHIPPABLE",
"currency_code": "USD",
"group_draft": false,
"invoice_date": "2018-11-12",
"invoice_number": "0001",
"memo": "This is a long contract",
"metadata": {
"caller_type": "API_V2_INVOICE",
"create_time": "2022-10-25T16:54:50Z",
"created_by_flow": "REGULAR_SINGLE",
"invoicer_view_url": "https://www.sandbox.paypal.com/invoice/details/INV2-XFXV-YW42-ZANU-4F33",
"last_update_time": "2022-10-25T16:54:50Z",
"recipient_view_url": "https://www.sandbox.paypal.com/invoice/p/#XFXVYW42ZANU4F33"
},
"note": "Thank you for your business.",
"payment_term": {
"due_date": "2018-11-22",
"term_type": "NET_10"
},
"reference": "deal-ref",
"viewed_by_recipient": false
},
"due_amount": {
"currency_code": "USD",
"value": "74.21"
},
"id": "INV2-XFXV-YW42-ZANU-4F33",
"invoicer": {
"additional_notes": "2-4",
"address": {
"address_line_1": "1234 First Street",
"address_line_2": "337673 Hillside Court",
"admin_area_1": "CA",
"admin_area_2": "Anytown",
"country_code": "US",
"postal_code": "98765"
},
"email_address": "merchant@example.com",
"logo_url": "https://example.com/logo.PNG",
"name": {
"full_name": "David Larusso",
"given_name": "David",
"surname": "Larusso"
},
"phones": [
{
"country_code": "001",
"national_number": "4085551234",
"phone_type": "MOBILE"
}
],
"tax_id": "ABcNkWSfb5ICTt73nD3QON1fnnpgNKBy- Jb5SeuGj185MNNw6g",
"website": "www.test.com"
},
"items": [
{
"description": "Elastic mat to practice yoga.",
"discount": {
"amount": {
"currency_code": "USD",
"value": "-2.50"
},
"percent": "5"
},
"id": "ITEM-5335764681676603X",
"name": "Yoga Mat",
"quantity": "1",
"tax": {
"amount": {
"currency_code": "USD",
"value": "3.27"
},
"id": "TAX-5XV24702TP4910056",
"name": "Sales Tax",
"percent": "7.25"
},
"unit_amount": {
"currency_code": "USD",
"value": "50.00"
},
"unit_of_measure": "QUANTITY"
},
{
"discount": {
"amount": {
"currency_code": "USD",
"value": "-5.00"
}
},
"id": "ITEM-1B467958Y9218273X",
"name": "Yoga t-shirt",
"quantity": "1",
"tax": {
"amount": {
"currency_code": "USD",
"value": "0.34"
},
"id": "TAX-5XV24702TP4910056",
"name": "Sales Tax",
"percent": "7.25"
},
"unit_amount": {
"currency_code": "USD",
"value": "10.00"
},
"unit_of_measure": "QUANTITY"
}
],
"links": [
{
"href": "https://api.sandbox.paypal.com/v2/invoicing/invoices/INV2-XFXV-YW42-ZANU-4F33",
"method": "GET",
"rel": "self"
},
{
"href": "https://api.sandbox.paypal.com/v2/invoicing/invoices/INV2-XFXV-YW42-ZANU-4F33/send",
"method": "POST",
"rel": "send"
},
{
"href": "https://api.sandbox.paypal.com/v2/invoicing/invoices/INV2-XFXV-YW42-ZANU-4F33",
"method": "PUT",
"rel": "replace"
},
{
"href": "https://api.sandbox.paypal.com/v2/invoicing/invoices/INV2-XFXV-YW42-ZANU-4F33",
"method": "DELETE",
"rel": "delete"
},
{
"href": "https://api.sandbox.paypal.com/v2/invoicing/invoices/INV2-XFXV-YW42-ZANU-4F33/payments",
"method": "POST",
"rel": "record-payment"
}
],
"primary_recipients": [
{
"billing_info": {
"address": {
"address_line_1": "1234 Main Street",
"admin_area_1": "CA",
"admin_area_2": "Anytown",
"country_code": "US",
"postal_code": "98765"
},
"email_address": "bill-me@example.com",
"name": {
"full_name": "Stephanie Meyers",
"given_name": "Stephanie",
"surname": "Meyers"
}
},
"shipping_info": {
"address": {
"address_line_1": "1234 Main Street",
"admin_area_1": "CA",
"admin_area_2": "Anytown",
"country_code": "US",
"postal_code": "98765"
},
"name": {
"full_name": "Stephanie Meyers",
"given_name": "Stephanie",
"surname": "Meyers"
}
}
}
],
"status": "DRAFT",
"unilateral": false
}
`)
var testInvoice paypal.Invoice
err := json.Unmarshal(testInvoiceJSONData, &testInvoice)
assert.Equal(t, nil, err) // if passed, means unmarshalling was successful
ctx := context.Background()
c, _ := paypal.NewClient(devTestClientID, devTestSecret, devAPIBaseSandBox)
_, _ = c.GetAccessToken(ctx)
invoice, err := c.GetInvoiceDetails(ctx, "INV2-XFXV-YW42-ZANU-4F33")
assert.Equal(t, nil, err) // if passed, means that request was successful
assertTwoInvoices(t, *invoice, testInvoice)
}

258
types.go
View File

@ -204,6 +204,264 @@ type (
CancelURL string `json:"cancel_url,omitempty"`
}
// Invoicing relates structures
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#invoices_generate-next-invoice-number
InvoiceNumber struct {
InvoiceNumberValue string `json:"invoice_number"`
}
// used in InvoiceAmountWithBreakdown
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-custom_amount
CustomAmount struct {
Label string `json:"label"`
Amount Money `json:"amount,omitempty"`
}
// Used in AggregatedDiscount
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-discount
InvoicingDiscount struct {
DiscountAmount Money `json:"amount,omitempty"`
Percent string `json:"percent,omitempty"`
}
// Used in InvoiceAmountWithBreakdown
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-aggregated_discount
AggregatedDiscount struct {
InvoiceDiscount InvoicingDiscount `json:"invoice_discount,omitempty"`
ItemDiscount *Money `json:"item_discount,omitempty"`
}
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-tax
InvoiceTax struct {
Name string `json:"name,omitempty"`
Percent string `json:"percent,omitempty"`
ID string `json:"id,omitempty"` // not mentioned here, but is still returned in response payload, when invoice is requested by ID.
Amount Money `json:"amount,omitempty"`
}
// Used in InvoiceAmountWithBreakdown struct
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-shipping_cost
InvoiceShippingCost struct {
Amount Money `json:"amount,omitempty"`
Tax InvoiceTax `json:"tax,omitempty"`
}
// Used in AmountSummaryDetail
// Doc: https://developer.paypal.com/docs/api/payments/v2/#definition-nrp-nrr_attributes
InvoiceAmountWithBreakdown struct {
Custom CustomAmount `json:"custom,omitempty"` // The custom amount to apply to an invoice.
Discount AggregatedDiscount `json:"discount,omitempty"`
ItemTotal Money `json:"item_total,omitempty"` // The subtotal for all items.
Shipping InvoiceShippingCost `json:"shipping,omitempty"` // The shipping fee for all items. Includes tax on shipping.
TaxTotal Money `json:"tax_total,omitempty"`
}
// Invoice AmountSummary
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-amount_summary_detail
AmountSummaryDetail struct {
Breakdown InvoiceAmountWithBreakdown `json:"breakdown,omitempty"`
Currency string `json:"currency_code,omitempty"`
Value string `json:"value,omitempty"`
}
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-partial_payment
InvoicePartialPayment struct {
AllowPartialPayment bool `json:"allow_partial_payment,omitempty"`
MinimumAmountDue Money `json:"minimum_amount_due,omitempty"` // Valid only when allow_partial_payment is true.
}
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-configuration
InvoiceConfiguration struct {
AllowTip bool `json:"allow_tip,omitempty"`
PartialPayment InvoicePartialPayment `json:"partial_payment,omitempty"`
TaxCalculatedAfterDiscount bool `json:"tax_calculated_after_discount,omitempty"`
TaxInclusive bool `json:"tax_inclusive,omitempty"`
TemplateId string `json:"template_id,omitempty"`
}
// used in InvoiceDetail structure
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-file_reference
InvoiceFileReference struct {
ContentType string `json:"content_type,omitempty"`
CreateTime string `json:"create_time,omitempty"`
ID string `json:"id,omitempty"`
URL string `json:"reference_url,omitempty"`
Size string `json:"size,omitempty"`
}
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-metadata
InvoiceAuditMetadata struct {
CreateTime string `json:"create_time,omitempty"`
CreatedBy string `json:"created_by,omitempty"`
LastUpdateTime string `json:"last_update_time,omitempty"`
LastUpdatedBy string `json:"last_updated_by,omitempty"`
CancelTime string `json:"cancel_time,omitempty"`
CancellledTimeBy string `json:"cancelled_by,omitempty"`
CreatedByFlow string `json:"created_by_flow,omitempty"`
FirstSentTime string `json:"first_sent_time,omitempty"`
InvoicerViewUrl string `json:"invoicer_view_url,omitempty"`
LastSentBy string `json:"last_sent_by,omitempty"`
LastSentTime string `json:"last_sent_time,omitempty"`
RecipientViewUrl string `json:"recipient_view_url,omitempty"`
}
// used in InvoiceDetail struct
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-invoice_payment_term
InvoicePaymentTerm struct {
TermType string `json:"term_type,omitempty"`
DueDate string `json:"due_date,omitempty"`
}
// used in Invoice struct
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-invoice_detail
InvoiceDetail struct {
CurrencyCode string `json:"currency_code"` // required, hence omitempty not used
Attachments []InvoiceFileReference `json:"attachments,omitempty"`
Memo string `json:"memo,omitempty"`
Note string `json:"note,omitempty"`
Reference string `json:"reference,omitempty"`
TermsAndConditions string `json:"terms_and_conditions,omitempty"`
InvoiceDate string `json:"invoice_date,omitempty"`
InvoiceNumber string `json:"invoice_number,omitempty"`
Metadata InvoiceAuditMetadata `json:"metadata,omitempty"` // The audit metadata.
PaymentTerm InvoicePaymentTerm `json:"payment_term,omitempty"` // payment due date for the invoice. Value is either but not both term_type or due_date.
}
// used in InvoicerInfo struct
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-phone_detail
InvoicerPhoneDetail struct {
CountryCode string `json:"country_code"`
NationalNumber string `json:"national_number"`
ExtensionNumber string `json:"extension_number,omitempty"`
PhoneType string `json:"phone_type,omitempty"`
}
// used in Invoice struct
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-invoicer_info
InvoicerInfo struct {
AdditionalNotes string `json:"additional_notes,omitempty"`
EmailAddress string `json:"email_address,omitempty"`
LogoUrl string `json:"logo_url,omitempty"`
Phones []InvoicerPhoneDetail `json:"phones,omitempty"`
TaxId string `json:"tax_id,omitempty"`
Website string `json:"website,omitempty"`
}
// Used in Invoice struct
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-item
InvoiceItem struct {
Name string `json:"name"`
Quantity string `json:"quantity"`
UnitAmount Money `json:"unit_amount"`
Description string `json:"description,omitempty"`
InvoiceDiscount InvoicingDiscount `json:"discount,omitempty"`
ID string `json:"id,omitempty"`
ItemDate string `json:"item_date,omitempty"`
Tax InvoiceTax `json:"tax,omitempty"`
UnitOfMeasure string `json:"unit_of_measure,omitempty"`
}
// used in InvoiceAddressPortable
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-address_details
InvoiceAddressDetails struct {
BuildingName string `json:"building_name,omitempty"`
DeliveryService string `json:"delivery_service,omitempty"`
StreetName string `json:"street_name,omitempty"`
StreetNumber string `json:"street_number,omitempty"`
StreetType string `json:"street_type,omitempty"`
SubBuilding string `json:"sub_building,omitempty"`
}
// used in InvoiceContactInfo
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-address_portable
InvoiceAddressPortable struct {
CountryCode string `json:"country_code"`
AddressDetails InvoiceAddressDetails `json:"address_details,omitempty"`
AddressLine1 string `json:"address_line_1,omitempty"`
AddressLine2 string `json:"address_line_2,omitempty"`
AddressLine3 string `json:"address_line_3,omitempty"`
AdminArea1 string `json:"admin_area_1,omitempty"`
AdminArea2 string `json:"admin_area_2,omitempty"`
AdminArea3 string `json:"admin_area_3,omitempty"`
AdminArea4 string `json:"admin_area_4,omitempty"`
PostalCode string `json:"postal_code,omitempty"`
}
// used in InvoicePaymentDetails
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-contact_information
InvoiceContactInfo struct {
BusinessName string `json:"business_name,omitempty"`
RecipientAddress InvoiceAddressPortable `json:"address,omitempty"` // address of the recipient.
RecipientName Name `json:"name,omitempty"` // The first and Last name of the recipient.
}
//used in InvoicePayments struct
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-payment_detail
InvoicePaymentDetails struct {
Method string `json:"method"`
Amount Money `json:"amount,omitempty"`
Note string `json:"note,omitempty"`
PaymentDate string `json:"payment_date,omitempty"`
PaymentID string `json:"payment_id,omitempty"`
ShippingInfo InvoiceContactInfo `json:"shipping_info,omitempty"` // The recipient's shipping information.
Type string `json:"type,omitempty"`
}
// used in Invoice
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-payments
InvoicePayments struct {
PaidAmount Money `json:"paid_amount,omitempty"`
Transactions []InvoicePaymentDetails `json:"transactions,omitempty"`
}
// used in InvoiceRecipientInfo
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-billing_info
InvoiceBillingInfo struct {
AdditionalInfo string `json:"additional_info,omitempty"`
EmailAddress string `json:"email_address,omitempty"`
Language string `json:"language,omitempty"`
Phones []InvoicerPhoneDetail `json:"phones,omitempty"` // invoice recipient's phone numbers.
}
// used in Invoice struct
// Doc:
InvoiceRecipientInfo struct {
BillingInfo InvoiceBillingInfo `json:"billing_info,omitempty"` // billing information for the invoice recipient.
ShippingInfo InvoiceContactInfo `json:"shipping_info,omitempty"` // recipient's shipping information.
}
// used in InvoiceRefund struct
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-refund_detail
InvoiceRefundDetails struct {
Method string `json:"method"`
RefundAmount Money `json:"amount,omitempty"`
RefundDate string `json:"refund_date,omitempty"`
RefundID string `json:"refund_id,omitempty"`
RefundType string `json:"type,omitempty"`
}
// used in Invoice struct
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-refunds
InvoiceRefund struct {
RefundAmount Money `json:"refund_amount,omitempty"`
RefundDetails []InvoiceRefundDetails `json:"transactions,omitempty"`
}
// used in Invoice struct
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#definition-email_address
InvoiceEmailAddress struct {
EmailAddress string `json:"email_address,omitempty"`
}
// to contain Invoice related fields
// Doc: https://developer.paypal.com/docs/api/invoicing/v2/#invoices_get
Invoice struct {
AdditionalRecipients []InvoiceEmailAddress `json:"additional_recipients,omitempty"` // An array of one or more CC: emails to which notifications are sent.
AmountSummary AmountSummaryDetail `json:"amount,omitempty"`
Configuration InvoiceConfiguration `json:"configuration,omitempty"`
Detail InvoiceDetail `json:"detail,omitempty"`
DueAmount Money `json:"due_amount,omitempty"` // balance amount outstanding after payments.
Gratuity Money `json:"gratuity,omitempty"` // amount paid by the payer as gratuity to the invoicer.
ID string `json:"id,omitempty"`
Invoicer InvoicerInfo `json:"invoicer,omitempty"`
Items []InvoiceItem `json:"items,omitempty"`
Links []Link `json:"links,omitempty"`
ParentID string `json:"parent_id,omitempty"`
Payments InvoicePayments `json:"payments,omitempty"`
PrimaryRecipients []InvoiceRecipientInfo `json:"primary_recipients,omitempty"`
Refunds InvoiceRefund `json:"refunds,omitempty"` // List of refunds against this invoice.
Status string `json:"status,omitempty"`
}
// Doc: https://developer.paypal.com/api/orders/v2/#definition-payment_method
PaymentMethod struct {
PayeePreferred PayeePreferred `json:"payee_preferred,omitempty"`