Skip to content
This repository was archived by the owner on Sep 11, 2018. It is now read-only.

Commit 0e0df9e

Browse files
amwolffdlebech
authored andcommitted
Add ApplicationCharge support (#107)
* A workaround an API returning only dates, but missing time and timezone. (#91) * Update recurringapplicationcharge_test.go due to updated decimal library
1 parent f5e2c87 commit 0e0df9e

15 files changed

+572
-12
lines changed

applicationcharge.go

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package goshopify
2+
3+
import (
4+
"fmt"
5+
"time"
6+
7+
"github.com/shopspring/decimal"
8+
)
9+
10+
const applicationChargesBasePath = "admin/application_charges"
11+
12+
// ApplicationChargeService is an interface for interacting with the
13+
// ApplicationCharge endpoints of the Shopify API.
14+
// See https://help.shopify.com/api/reference/billing/applicationcharge
15+
type ApplicationChargeService interface {
16+
Create(ApplicationCharge) (*ApplicationCharge, error)
17+
Get(int, interface{}) (*ApplicationCharge, error)
18+
List(interface{}) ([]ApplicationCharge, error)
19+
Activate(ApplicationCharge) (*ApplicationCharge, error)
20+
}
21+
22+
type ApplicationChargeServiceOp struct {
23+
client *Client
24+
}
25+
26+
type ApplicationCharge struct {
27+
ID int `json:"id"`
28+
Name string `json:"name"`
29+
APIClientID int `json:"api_client_id"`
30+
Price *decimal.Decimal `json:"price"`
31+
Status string `json:"status"`
32+
ReturnURL string `json:"return_url"`
33+
Test *bool `json:"test"`
34+
CreatedAt *time.Time `json:"created_at"`
35+
UpdatedAt *time.Time `json:"updated_at"`
36+
ChargeType *string `json:"charge_type"`
37+
DecoratedReturnURL string `json:"decorated_return_url"`
38+
ConfirmationURL string `json:"confirmation_url"`
39+
}
40+
41+
// ApplicationChargeResource represents the result from the
42+
// admin/application_charges{/X{/activate.json}.json}.json endpoints.
43+
type ApplicationChargeResource struct {
44+
Charge *ApplicationCharge `json:"application_charge"`
45+
}
46+
47+
// ApplicationChargesResource represents the result from the
48+
// admin/application_charges.json endpoint.
49+
type ApplicationChargesResource struct {
50+
Charges []ApplicationCharge `json:"application_charges"`
51+
}
52+
53+
// Create creates new application charge.
54+
func (a ApplicationChargeServiceOp) Create(charge ApplicationCharge) (*ApplicationCharge, error) {
55+
path := fmt.Sprintf("%s.json", applicationChargesBasePath)
56+
resource := &ApplicationChargeResource{}
57+
return resource.Charge, a.client.Post(path, ApplicationChargeResource{Charge: &charge}, resource)
58+
}
59+
60+
// Get gets individual application charge.
61+
func (a ApplicationChargeServiceOp) Get(chargeID int, options interface{}) (*ApplicationCharge, error) {
62+
path := fmt.Sprintf("%s/%d.json", applicationChargesBasePath, chargeID)
63+
resource := &ApplicationChargeResource{}
64+
return resource.Charge, a.client.Get(path, resource, options)
65+
}
66+
67+
// List gets all application charges.
68+
func (a ApplicationChargeServiceOp) List(options interface{}) ([]ApplicationCharge, error) {
69+
path := fmt.Sprintf("%s.json", applicationChargesBasePath)
70+
resource := &ApplicationChargesResource{}
71+
return resource.Charges, a.client.Get(path, resource, options)
72+
}
73+
74+
// Activate activates application charge.
75+
func (a ApplicationChargeServiceOp) Activate(charge ApplicationCharge) (*ApplicationCharge, error) {
76+
path := fmt.Sprintf("%s/%d/activate.json", applicationChargesBasePath, charge.ID)
77+
resource := &ApplicationChargeResource{}
78+
return resource.Charge, a.client.Post(path, ApplicationChargeResource{Charge: &charge}, resource)
79+
}

applicationcharge_test.go

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package goshopify
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
"time"
7+
8+
"github.com/shopspring/decimal"
9+
"gopkg.in/jarcoal/httpmock.v1"
10+
)
11+
12+
// applicationChargeTests tests if the fields are properly parsed.
13+
func applicationChargeTests(t *testing.T, charge ApplicationCharge) {
14+
var nilTest *bool
15+
cases := []struct {
16+
field string
17+
expected interface{}
18+
actual interface{}
19+
}{
20+
{"ID", 1017262355, charge.ID},
21+
{"Name", "Super Duper Expensive action", charge.Name},
22+
{"APIClientID", 755357713, charge.APIClientID},
23+
{"Price", decimal.NewFromFloat(100.00).String(), charge.Price.String()},
24+
{"Status", "pending", charge.Status},
25+
{"ReturnURL", "http://super-duper.shopifyapps.com/", charge.ReturnURL},
26+
{"Test", nilTest, charge.Test},
27+
{"CreatedAt", "2018-07-05T13:11:28-04:00", charge.CreatedAt.Format(time.RFC3339)},
28+
{"UpdatedAt", "2018-07-05T13:11:28-04:00", charge.UpdatedAt.Format(time.RFC3339)},
29+
{
30+
"DecoratedReturnURL",
31+
"http://super-duper.shopifyapps.com/?charge_id=1017262355",
32+
charge.DecoratedReturnURL,
33+
},
34+
{
35+
"ConfirmationURL",
36+
"https://apple.myshopify.com/admin/charges/1017262355/confirm_application_charge?sign" +
37+
"ature=BAhpBBMxojw%3D--1139a82a3433b1a6771786e03f02300440e11883",
38+
charge.ConfirmationURL,
39+
},
40+
}
41+
42+
for _, c := range cases {
43+
if c.expected != c.actual {
44+
t.Errorf("ApplicationCharge.%s returned %v, expected %v", c.field, c.actual, c.expected)
45+
}
46+
}
47+
}
48+
49+
func TestApplicationChargeServiceOp_Create(t *testing.T) {
50+
setup()
51+
defer teardown()
52+
53+
httpmock.RegisterResponder(
54+
"POST",
55+
"https://fooshop.myshopify.com/admin/application_charges.json",
56+
httpmock.NewBytesResponder(200, loadFixture("applicationcharge.json")),
57+
)
58+
59+
p := decimal.NewFromFloat(100.00)
60+
charge := ApplicationCharge{
61+
Name: "Super Duper Expensive action",
62+
Price: &p,
63+
ReturnURL: "http://super-duper.shopifyapps.com",
64+
}
65+
66+
returnedCharge, err := client.ApplicationCharge.Create(charge)
67+
if err != nil {
68+
t.Errorf("ApplicationCharge.Create returned an error: %v", err)
69+
}
70+
71+
applicationChargeTests(t, *returnedCharge)
72+
}
73+
74+
func TestApplicationChargeServiceOp_Get(t *testing.T) {
75+
setup()
76+
defer teardown()
77+
78+
httpmock.RegisterResponder(
79+
"GET",
80+
"https://fooshop.myshopify.com/admin/application_charges/1.json",
81+
httpmock.NewStringResponder(200, `{"application_charge": {"id":1}}`),
82+
)
83+
84+
charge, err := client.ApplicationCharge.Get(1, nil)
85+
if err != nil {
86+
t.Errorf("ApplicationCharge.Get returned an error: %v", err)
87+
}
88+
89+
expected := &ApplicationCharge{ID: 1}
90+
if !reflect.DeepEqual(charge, expected) {
91+
t.Errorf("ApplicationCharge.Get returned %+v, expected %+v", charge, expected)
92+
}
93+
}
94+
95+
func TestApplicationChargeServiceOp_List(t *testing.T) {
96+
setup()
97+
defer teardown()
98+
99+
httpmock.RegisterResponder(
100+
"GET",
101+
"https://fooshop.myshopify.com/admin/application_charges.json",
102+
httpmock.NewStringResponder(200, `{"application_charges": [{"id":1},{"id":2}]}`),
103+
)
104+
105+
charges, err := client.ApplicationCharge.List(nil)
106+
if err != nil {
107+
t.Errorf("ApplicationCharge.List returned an error: %v", err)
108+
}
109+
110+
expected := []ApplicationCharge{{ID: 1}, {ID: 2}}
111+
if !reflect.DeepEqual(charges, expected) {
112+
t.Errorf("ApplicationCharge.List returned %+v, expected %+v", charges, expected)
113+
}
114+
}
115+
116+
func TestApplicationChargeServiceOp_Activate(t *testing.T) {
117+
setup()
118+
defer teardown()
119+
120+
httpmock.RegisterResponder(
121+
"POST",
122+
"https://fooshop.myshopify.com/admin/application_charges/455696195/activate.json",
123+
httpmock.NewStringResponder(
124+
200,
125+
`{"application_charge":{"id":455696195,"status":"active"}}`,
126+
),
127+
)
128+
129+
charge := ApplicationCharge{
130+
ID: 455696195,
131+
Status: "accepted",
132+
}
133+
134+
returnedCharge, err := client.ApplicationCharge.Activate(charge)
135+
if err != nil {
136+
t.Errorf("ApplicationCharge.Activate returned an error: %v", err)
137+
}
138+
139+
expected := &ApplicationCharge{ID: 455696195, Status: "active"}
140+
if !reflect.DeepEqual(returnedCharge, expected) {
141+
t.Errorf("ApplicationCharge.Activate returned %+v, expected %+v", charge, expected)
142+
}
143+
}

fixtures/applicationcharge.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"application_charge": {
3+
"id": 1017262355,
4+
"name": "Super Duper Expensive action",
5+
"api_client_id": 755357713,
6+
"price": "100.00",
7+
"status": "pending",
8+
"return_url": "http://super-duper.shopifyapps.com/",
9+
"test": null,
10+
"created_at": "2018-07-05T13:11:28-04:00",
11+
"updated_at": "2018-07-05T13:11:28-04:00",
12+
"charge_type": null,
13+
"decorated_return_url": "http://super-duper.shopifyapps.com/?charge_id=1017262355",
14+
"confirmation_url": "https://apple.myshopify.com/admin/charges/1017262355/confirm_application_charge?signature=BAhpBBMxojw%3D--1139a82a3433b1a6771786e03f02300440e11883"
15+
}
16+
}

fixtures/reccuringapplicationcharge.json fixtures/reccuringapplicationcharge/reccuringapplicationcharge.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@
1717
"decorated_return_url": "http://super-duper.shopifyapps.com/?charge_id=1029266948",
1818
"confirmation_url": "https://apple.myshopify.com/admin/charges/1029266948/confirm_recurring_application_charge?signature=BAhpBAReWT0%3D--b51a6db06a3792c4439783fcf0f2e89bf1c9df68"
1919
}
20-
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"recurring_application_charge": {
3+
"id": 1029266948,
4+
"name": "Super Duper Plan",
5+
"api_client_id": 755357713,
6+
"price": "10.00",
7+
"status": "pending",
8+
"return_url": "http://super-duper.shopifyapps.com/",
9+
"billing_on": "2018-06-05",
10+
"created_at": "2018-06-05",
11+
"updated_at": "2018-06-05",
12+
"test": null,
13+
"activated_on": "2018-06-05",
14+
"trial_ends_on": "2018-06-05",
15+
"cancelled_on": "2018-06-05",
16+
"trial_days": 0,
17+
"decorated_return_url": "http://super-duper.shopifyapps.com/?charge_id=1029266948",
18+
"confirmation_url": "https://apple.myshopify.com/admin/charges/1029266948/confirm_recurring_application_charge?signature=BAhpBAReWT0%3D--b51a6db06a3792c4439783fcf0f2e89bf1c9df68"
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"recurring_application_charge": {
3+
"id": 1029266948,
4+
"name": "Super Duper Plan",
5+
"api_client_id": 755357713,
6+
"price": "10.00",
7+
"status": "pending",
8+
"return_url": "http://super-duper.shopifyapps.com/",
9+
"billing_on": false,
10+
"created_at": false,
11+
"updated_at": false,
12+
"test": null,
13+
"activated_on": false,
14+
"trial_ends_on": false,
15+
"cancelled_on": false,
16+
"trial_days": 0,
17+
"decorated_return_url": "http://super-duper.shopifyapps.com/?charge_id=1029266948",
18+
"confirmation_url": "https://apple.myshopify.com/admin/charges/1029266948/confirm_recurring_application_charge?signature=BAhpBAReWT0%3D--b51a6db06a3792c4439783fcf0f2e89bf1c9df68"
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"recurring_application_charge": {
3+
"id": 1029266948,
4+
"name": "Super Duper Plan",
5+
"api_client_id": 755357713,
6+
"price": "10.00",
7+
"status": "pending",
8+
"return_url": "http://super-duper.shopifyapps.com/",
9+
"billing_on": null,
10+
"created_at": null,
11+
"updated_at": null,
12+
"test": null,
13+
"activated_on": "ptk 27 lip 14:24:13 2018 CEST",
14+
"trial_ends_on": null,
15+
"cancelled_on": null,
16+
"trial_days": 0,
17+
"decorated_return_url": "http://super-duper.shopifyapps.com/?charge_id=1029266948",
18+
"confirmation_url": "https://apple.myshopify.com/admin/charges/1029266948/confirm_recurring_application_charge?signature=BAhpBAReWT0%3D--b51a6db06a3792c4439783fcf0f2e89bf1c9df68"
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"recurring_application_charge": {
3+
"id": 1029266948,
4+
"name": "Super Duper Plan",
5+
"api_client_id": 755357713,
6+
"price": "10.00",
7+
"status": "pending",
8+
"return_url": "http://super-duper.shopifyapps.com/",
9+
"billing_on": "ptk 27 lip 14:24:13 2018 CEST",
10+
"created_at": null,
11+
"updated_at": null,
12+
"test": null,
13+
"activated_on": null,
14+
"trial_ends_on": null,
15+
"cancelled_on": null,
16+
"trial_days": 0,
17+
"decorated_return_url": "http://super-duper.shopifyapps.com/?charge_id=1029266948",
18+
"confirmation_url": "https://apple.myshopify.com/admin/charges/1029266948/confirm_recurring_application_charge?signature=BAhpBAReWT0%3D--b51a6db06a3792c4439783fcf0f2e89bf1c9df68"
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"recurring_application_charge": {
3+
"id": 1029266948,
4+
"name": "Super Duper Plan",
5+
"api_client_id": 755357713,
6+
"price": "10.00",
7+
"status": "pending",
8+
"return_url": "http://super-duper.shopifyapps.com/",
9+
"billing_on": null,
10+
"created_at": null,
11+
"updated_at": null,
12+
"test": null,
13+
"activated_on": null,
14+
"trial_ends_on": null,
15+
"cancelled_on": "ptk 27 lip 14:24:13 2018 CEST",
16+
"trial_days": 0,
17+
"decorated_return_url": "http://super-duper.shopifyapps.com/?charge_id=1029266948",
18+
"confirmation_url": "https://apple.myshopify.com/admin/charges/1029266948/confirm_recurring_application_charge?signature=BAhpBAReWT0%3D--b51a6db06a3792c4439783fcf0f2e89bf1c9df68"
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"recurring_application_charge": {
3+
"id": 1029266948,
4+
"name": "Super Duper Plan",
5+
"api_client_id": 755357713,
6+
"price": "10.00",
7+
"status": "pending",
8+
"return_url": "http://super-duper.shopifyapps.com/",
9+
"billing_on": null,
10+
"created_at": "ptk 27 lip 14:24:13 2018 CEST",
11+
"updated_at": null,
12+
"test": null,
13+
"activated_on": null,
14+
"trial_ends_on": null,
15+
"cancelled_on": null,
16+
"trial_days": 0,
17+
"decorated_return_url": "http://super-duper.shopifyapps.com/?charge_id=1029266948",
18+
"confirmation_url": "https://apple.myshopify.com/admin/charges/1029266948/confirm_recurring_application_charge?signature=BAhpBAReWT0%3D--b51a6db06a3792c4439783fcf0f2e89bf1c9df68"
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"recurring_application_charge": {
3+
"id": 1029266948,
4+
"name": "Super Duper Plan",
5+
"api_client_id": 755357713,
6+
"price": "10.00",
7+
"status": "pending",
8+
"return_url": "http://super-duper.shopifyapps.com/",
9+
"billing_on": null,
10+
"created_at": null,
11+
"updated_at": null,
12+
"test": null,
13+
"activated_on": null,
14+
"trial_ends_on": "ptk 27 lip 14:24:13 2018 CEST",
15+
"cancelled_on": null,
16+
"trial_days": 0,
17+
"decorated_return_url": "http://super-duper.shopifyapps.com/?charge_id=1029266948",
18+
"confirmation_url": "https://apple.myshopify.com/admin/charges/1029266948/confirm_recurring_application_charge?signature=BAhpBAReWT0%3D--b51a6db06a3792c4439783fcf0f2e89bf1c9df68"
19+
}
20+
}

0 commit comments

Comments
 (0)