@@ -16,19 +16,48 @@ import (
1616
1717var ErrRateLimited = errors .New ("rate limited" )
1818
19+ type Option func (o * Client ) * Client
20+
21+ func WithCache (cache Cache ) Option {
22+ return func (c * Client ) * Client {
23+ c .cache = cache
24+ return c
25+ }
26+ }
27+
1928// NewClient returns new Client struct
2029// APIBase is a base API URL, for testing you can use paypal.APIBaseSandBox
21- func NewClient (clientID string , secret string , APIBase string ) (* Client , error ) {
30+ func NewClient (ctx context. Context , clientID string , secret string , APIBase string , options ... Option ) (* Client , error ) {
2231 if clientID == "" || secret == "" || APIBase == "" {
2332 return nil , errors .New ("ClientID, Secret and APIBase are required to create a Client" )
2433 }
2534
26- return & Client {
35+ cli := & Client {
2736 Client : & http.Client {},
2837 ClientID : clientID ,
2938 Secret : secret ,
3039 APIBase : APIBase ,
31- }, nil
40+ }
41+
42+ for _ , option := range options {
43+ cli = option (cli )
44+ }
45+ cli .checkCacheToken (ctx )
46+ return cli , nil
47+ }
48+
49+ func (c * Client ) checkCacheToken (ctx context.Context ) {
50+ if c .cache == nil {
51+ return
52+ }
53+
54+ token , err := c .cache .GetToken (ctx , c .ClientID )
55+ if err != nil {
56+ return
57+ }
58+ if token != nil && token .Token != "" {
59+ c .SetAccessTokenWithExpiry (token .Token , token .ExpiresAt )
60+ }
3261}
3362
3463// GetAccessToken returns struct of TokenResponse
@@ -50,6 +79,20 @@ func (c *Client) GetAccessToken(ctx context.Context) (*TokenResponse, error) {
5079 if response .Token != "" {
5180 c .Token = response
5281 c .tokenExpiresAt = time .Now ().Add (time .Duration (response .ExpiresIn ) * time .Second )
82+
83+ if c .cache != nil {
84+ token := & CacheToken {
85+ RefreshToken : response .RefreshToken ,
86+ Token : response .Token ,
87+ Type : response .Type ,
88+ ExpiresIn : int64 (response .ExpiresIn ),
89+ ExpiresAt : c .tokenExpiresAt .Unix (),
90+ }
91+ err = c .cache .SetToken (ctx , c .ClientID , token )
92+ if err != nil {
93+ return response , err
94+ }
95+ }
5396 }
5497
5598 return response , err
@@ -68,6 +111,16 @@ func (c *Client) SetAccessToken(token string) {
68111 c .tokenExpiresAt = time.Time {}
69112}
70113
114+ // SetAccessTokenWithExpiry sets saved token to current client with expiry time
115+ func (c * Client ) SetAccessTokenWithExpiry (token string , expiresAt int64 ) {
116+ c .Token = & TokenResponse {
117+ Token : token ,
118+ }
119+ if expiresAt > 0 {
120+ c .tokenExpiresAt = time .Unix (expiresAt , 0 )
121+ }
122+ }
123+
71124// SetLog will set/change the output destination.
72125// If log file is set paypal will log all requests and responses to this Writer
73126func (c * Client ) SetLog (log io.Writer ) {
0 commit comments