forked from ewancook/fixr
/
stripe.go
113 lines (100 loc) · 2.64 KB
/
stripe.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package fixr
import (
"bytes"
"fmt"
"github.com/pkg/errors"
)
const (
key string = "pk_live_Jc9zYhZyq3a4JviHWZFBFRdp"
ua string = "stripe.js/604c5e8"
)
type stripeError struct {
Type string `json:"type"`
Message string `json:"message"`
Param string `json:"param"`
Code string `json:"code,omitempty"`
}
type token struct {
Token string `json:"id"`
Card struct {
ID string `json:"id"`
} `json:"card"`
Error *stripeError `json:"error,omitempty"`
}
func (t *token) error() error {
if t.Error != nil {
return fmt.Errorf("%s (code: %s; type: %s; param: %s)", t.Error.Message, t.Error.Code, t.Error.Type, t.Error.Param)
}
return nil
}
func (t *token) clearError() {
t.Error = nil
}
type stripeUser struct {
UserID string `json:"stripe_id"`
Cards []stripeCard `json:"cards"`
}
type stripeCard struct {
CardID string `json:"stripe_id"`
Last4 string `json:"last4"`
Brand string `json:"brand"`
ExpiryMonth int `json:"exp_month"`
ExpiryYear int `json:"exp_year"`
Country string `json:"country"`
}
type tokenRequest struct {
apiError
User *stripeUser `json:"stripe_user"`
}
// HasCard checks for the existence of a saved card in the user's FIXR account.
// The result and an error, if encountered, will be returned.
func (c *Client) HasCard() (existingCards bool, returnErr error) {
if c.StripeUser == nil {
return
}
if err := c.get(meURL, true, c); err != nil {
returnErr = errors.Wrap(err, "error updating stripe details")
}
existingCards = len(c.StripeUser.Cards) != 0
return
}
func encodeAddCardPayload(pl payload) (*bytes.Buffer, error) {
data := new(bytes.Buffer)
urlValues, err := buildURLValues(pl)
if err != nil {
return nil, err
}
data.WriteString(urlValues.Encode())
return data, nil
}
// AddCard saves a card to the user's FIXR account, given the card details.
// An error will be returned if encountered
func (c *Client) AddCard(num, month, year, cvc, zip string) error {
token := token{}
pl := payload{
"payment_user_agent": ua,
"key": key,
"card[number]": num,
"card[exp_month]": month,
"card[exp_year]": year,
"card[cvc]": cvc,
"card[address_zip]": zip,
}
data, err := encodeAddCardPayload(pl)
if err != nil {
return err
}
if err := c.post(cardURL, data, false, &token); err != nil {
return errors.Wrap(err, "error retrieving tokens")
}
tokenReq := tokenRequest{}
tokenData, err := jsonifyPayload(payload{"token": &token.Token})
if err != nil {
return err
}
if err := c.post(tokenURL, tokenData, true, &tokenReq); err != nil {
return errors.Wrap(err, "error sending tokens")
}
c.StripeUser = tokenReq.User
return nil
}