diff --git a/billing.go b/billing.go index fa6d461..fb06e9b 100644 --- a/billing.go +++ b/billing.go @@ -29,7 +29,7 @@ type ( CreateAgreementResponse struct { Name string `json:"name,omitempty"` Description string `json:"description,omitempty"` - Plan BillingPlan `json:"plan,omitempty"` + Plan BillingPlan `json:"plan,omitempty"` Links []Link `json:"links,omitempty"` StartTime time.Time `json:"start_time,omitempty"` } @@ -37,7 +37,7 @@ type ( // CreateAgreementResp. // // Deprecated: use CreateAgreementResponse instead. - CreateAgreementResp = CreateAgreementResponse + CreateAgreementResp = CreateAgreementResponse // BillingPlanListParams BillingPlanListParams struct { @@ -100,6 +100,7 @@ func (c *Client) ActivatePlan(ctx context.Context, planID string) error { // CreateBillingAgreement creates an agreement for specified plan // Endpoint: POST /v1/payments/billing-agreements +// Deprecated: Use POST /v1/billing-agreements/agreements func (c *Client) CreateBillingAgreement(ctx context.Context, a BillingAgreement) (*CreateAgreementResponse, error) { // PayPal needs only ID, so we will remove all fields except Plan ID a.Plan = BillingPlan{ diff --git a/billing_agreements.go b/billing_agreements.go new file mode 100644 index 0000000..2fa1b3b --- /dev/null +++ b/billing_agreements.go @@ -0,0 +1,68 @@ +package paypal + +import ( + "context" + "fmt" +) + +// CreatePaypalBillingAgreementToken - Use this call to create a billing agreement token +// Endpoint: POST /v1/billing-agreements/agreement-tokens +func (c *Client) CreatePaypalBillingAgreementToken( + ctx context.Context, + description *string, + shippingAddress *ShippingAddress, + payer *Payer, + plan *BillingPlan, +) (*BillingAgreementToken, error) { + type createBARequest struct { + Description *string `json:"description,omitempty"` + ShippingAddress *ShippingAddress `json:"shipping_address,omitempty"` + Payer *Payer `json:"payer"` + Plan *BillingPlan `json:"plan"` + } + + billingAgreementToken := &BillingAgreementToken{} + + req, err := c.NewRequest( + ctx, + "POST", + fmt.Sprintf("%s%s", c.APIBase, "/v1/billing-agreements/agreement-tokens"), + createBARequest{Description: description, ShippingAddress: shippingAddress, Payer: payer, Plan: plan}) + if err != nil { + return nil, err + } + + if err = c.SendWithAuth(req, billingAgreementToken); err != nil { + return billingAgreementToken, err + } + + return billingAgreementToken, nil +} + +// CreatePaypalBillingAgreementFromToken - Use this call to create a billing agreement +// Endpoint: POST /v1/billing-agreements/agreements +func (c *Client) CreatePaypalBillingAgreementFromToken( + ctx context.Context, + tokenID string, +) (*BillingAgreementFromToken, error) { + type createBARequest struct { + TokenID string `json:"token_id"` + } + + billingAgreement := &BillingAgreementFromToken{} + + req, err := c.NewRequest( + ctx, + "POST", + fmt.Sprintf("%s%s", c.APIBase, "/v1/billing-agreements/agreements"), + createBARequest{TokenID: tokenID}) + if err != nil { + return nil, err + } + + if err = c.SendWithAuth(req, billingAgreement); err != nil { + return billingAgreement, err + } + + return billingAgreement, nil +} diff --git a/types.go b/types.go index a9875fe..1e5f0dc 100644 --- a/types.go +++ b/types.go @@ -328,6 +328,31 @@ type ( OverrideMerchantPreferences *MerchantPreferences `json:"override_merchant_preferences,omitempty"` } + // BillingAgreementFromToken struct + BillingAgreementFromToken struct { + ID string `json:"id,omitempty"` + Description string `json:"description,omitempty"` + Payer *Payer `json:"payer,omitempty"` + Plan BillingPlan `json:"plan,omitempty"` + Links []Link `json:"links,omitempty"` + } + + // BillingAgreementToken response struct + BillingAgreementToken struct { + Links []Link `json:"links,omitempty"` + TokenID string `json:"token_id,omitempty"` + } + + // Plan struct + Plan struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + CreateTime string `json:"create_time,omitempty"` + UpdateTime string `json:"update_time,omitempty"` + PaymentDefinitions []PaymentDefinition `json:"payment_definitions,omitempty"` + } + // BillingInfo struct BillingInfo struct { OutstandingBalance AmountPayout `json:"outstanding_balance,omitempty"` diff --git a/unit_test.go b/unit_test.go index ab8b8d0..500c030 100644 --- a/unit_test.go +++ b/unit_test.go @@ -392,6 +392,16 @@ func (ts *webprofileTestServer) ServeHTTP(w http.ResponseWriter, r *http.Request ts.deleteinvalid(w, r) } } + if r.RequestURI == "/v1/billing-agreements/agreement-tokens" { + if r.Method == "POST" { + ts.createWithoutName(w, r) + } + } + if r.RequestURI == "/v1/billing-agreements/agreements" { + if r.Method == "POST" { + ts.createWithoutName(w, r) + } + } } func (ts *webprofileTestServer) create(w http.ResponseWriter, r *http.Request) { @@ -771,4 +781,39 @@ func TestDeleteWebProfile_invalid(t *testing.T) { t.Fatal(err) } -} \ No newline at end of file +} + +func TestCreatePaypalBillingAgreementToken(t *testing.T) { + + ts := httptest.NewServer(&webprofileTestServer{t: t}) + defer ts.Close() + + c, _ := NewClient("foo", "bar", ts.URL) + description := "name A" + + _, err := c.CreatePaypalBillingAgreementToken( + context.Background(), + &description, + &ShippingAddress{RecipientName: "Name", Type: "Type", Line1: "Line1", Line2: "Line2"}, + &Payer{PaymentMethod: "paypal"}, + &BillingPlan{ID: "id B", Name: "name B", Description: "description B", Type: "type B"}) + + if err != nil { + t.Fatal(err) + } + +} + +func TestCreatePaypalBillingAgreementFromToken(t *testing.T) { + + ts := httptest.NewServer(&webprofileTestServer{t: t}) + defer ts.Close() + + c, _ := NewClient("foo", "bar", ts.URL) + + _, err := c.CreatePaypalBillingAgreementFromToken(context.Background(), "BillingAgreementToken") + + if err != nil { + t.Fatal(err) + } +}