-
Notifications
You must be signed in to change notification settings - Fork 274
/
webhooks.go
144 lines (123 loc) · 4.78 KB
/
webhooks.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package paypal
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
)
// CreateWebhook - Subscribes your webhook listener to events.
// Endpoint: POST /v1/notifications/webhooks
func (c *Client) CreateWebhook(ctx context.Context, createWebhookRequest *CreateWebhookRequest) (*Webhook, error) {
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/notifications/webhooks"), createWebhookRequest)
webhook := &Webhook{}
if err != nil {
return webhook, err
}
err = c.SendWithAuth(req, webhook)
return webhook, err
}
// GetWebhook - Shows details for a webhook, by ID.
// Endpoint: GET /v1/notifications/webhooks/ID
func (c *Client) GetWebhook(ctx context.Context, webhookID string) (*Webhook, error) {
req, err := c.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/notifications/webhooks/", webhookID), nil)
webhook := &Webhook{}
if err != nil {
return webhook, err
}
err = c.SendWithAuth(req, webhook)
return webhook, err
}
// UpdateWebhook - Updates a webhook to replace webhook fields with new values.
// Endpoint: PATCH /v1/notifications/webhooks/ID
func (c *Client) UpdateWebhook(ctx context.Context, webhookID string, fields []WebhookField) (*Webhook, error) {
req, err := c.NewRequest(ctx, http.MethodPatch, fmt.Sprintf("%s/v1/notifications/webhooks/%s", c.APIBase, webhookID), fields)
webhook := &Webhook{}
if err != nil {
return webhook, err
}
err = c.SendWithAuth(req, webhook)
return webhook, err
}
// ListWebhooks - Lists webhooks for an app.
// Endpoint: GET /v1/notifications/webhooks
func (c *Client) ListWebhooks(ctx context.Context, anchorType string) (*ListWebhookResponse, error) {
if len(anchorType) == 0 {
anchorType = AncorTypeApplication
}
req, err := c.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s%s", c.APIBase, "/v1/notifications/webhooks"), nil)
q := req.URL.Query()
q.Add("anchor_type", anchorType)
req.URL.RawQuery = q.Encode()
resp := &ListWebhookResponse{}
if err != nil {
return nil, err
}
err = c.SendWithAuth(req, resp)
return resp, err
}
// DeleteWebhook - Deletes a webhook, by ID.
// Endpoint: DELETE /v1/notifications/webhooks/ID
func (c *Client) DeleteWebhook(ctx context.Context, webhookID string) error {
req, err := c.NewRequest(ctx, http.MethodDelete, fmt.Sprintf("%s/v1/notifications/webhooks/%s", c.APIBase, webhookID), nil)
if err != nil {
return err
}
err = c.SendWithAuth(req, nil)
return err
}
// VerifyWebhookSignature - Use this to verify the signature of a webhook recieved from paypal.
// Endpoint: POST /v1/notifications/verify-webhook-signature
func (c *Client) VerifyWebhookSignature(ctx context.Context, httpReq *http.Request, webhookID string) (*VerifyWebhookResponse, error) {
type verifyWebhookSignatureRequest struct {
AuthAlgo string `json:"auth_algo,omitempty"`
CertURL string `json:"cert_url,omitempty"`
TransmissionID string `json:"transmission_id,omitempty"`
TransmissionSig string `json:"transmission_sig,omitempty"`
TransmissionTime string `json:"transmission_time,omitempty"`
WebhookID string `json:"webhook_id,omitempty"`
Event json.RawMessage `json:"webhook_event,omitempty"`
}
// Read the content
var bodyBytes []byte
if httpReq.Body != nil {
bodyBytes, _ = io.ReadAll(httpReq.Body)
} else {
return nil, errors.New("cannot verify webhook for HTTP Request with empty body")
}
// Restore the io.ReadCloser to its original state
httpReq.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
verifyRequest := verifyWebhookSignatureRequest{
AuthAlgo: httpReq.Header.Get("PAYPAL-AUTH-ALGO"),
CertURL: httpReq.Header.Get("PAYPAL-CERT-URL"),
TransmissionID: httpReq.Header.Get("PAYPAL-TRANSMISSION-ID"),
TransmissionSig: httpReq.Header.Get("PAYPAL-TRANSMISSION-SIG"),
TransmissionTime: httpReq.Header.Get("PAYPAL-TRANSMISSION-TIME"),
WebhookID: webhookID,
Event: json.RawMessage(bodyBytes),
}
response := &VerifyWebhookResponse{}
req, err := c.NewRequest(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/notifications/verify-webhook-signature"), verifyRequest)
if err != nil {
return nil, err
}
if err = c.SendWithAuth(req, response); err != nil {
return nil, err
}
return response, nil
}
// GetWebhookEventTypes - Lists all webhook event types.
// Endpoint: GET /v1/notifications/webhooks-event-types
func (c *Client) GetWebhookEventTypes(ctx context.Context) (*WebhookEventTypesResponse, error) {
req, err := c.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s%s", c.APIBase, "/v1/notifications/webhooks-event-types"), nil)
q := req.URL.Query()
req.URL.RawQuery = q.Encode()
resp := &WebhookEventTypesResponse{}
if err != nil {
return nil, err
}
err = c.SendWithAuth(req, resp)
return resp, err
}