forked from go-packages/paypal
Add functions of create, get, update, delete and list webhooks (#146)
* Add webhook creation function * Add webhook list function * Add webhook delete function * Add webhook get function * Add webhook update function * Update documentation related to webhooks * Fix addressed issues on code review
This commit is contained in:
parent
497963d8a5
commit
21b349dbdc
41
README.md
41
README.md
|
@ -42,6 +42,11 @@ Currently supports **v2** only, if you want to use **v1**, use **v1.1.4** git ta
|
|||
* PATCH /v2/payments/billing-plans/***ID***
|
||||
* POST /v2/payments/billing-agreements
|
||||
* POST /v2/payments/billing-agreements/***TOKEN***/agreement-execute
|
||||
* POST /v1/notifications/webhooks
|
||||
* GET /v1/notifications/webhooks
|
||||
* GET /v1/notifications/webhooks/**ID**
|
||||
* PATCH /v1/notifications/webhooks/**ID**
|
||||
* DELETE /v1/notifications/webhooks/**ID**
|
||||
* POST /v1/notifications/verify-webhook-signature
|
||||
|
||||
### Missing endpoints
|
||||
|
@ -281,6 +286,42 @@ c.GetCreditCard("CARD-ID-123")
|
|||
c.GetCreditCards(nil)
|
||||
```
|
||||
|
||||
### Webhooks
|
||||
```go
|
||||
// Create a webhook
|
||||
c.CreateWebhook(paypal.CreateWebhookRequest{
|
||||
URL: "webhook URL",
|
||||
EventTypes: []paypal.WebhookEventType{
|
||||
paypal.WebhookEventType{
|
||||
Name: "PAYMENT.AUTHORIZATION.CREATED",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Update a registered webhook
|
||||
c.UpdateWebhook("WebhookID", []paypal.WebhookField{
|
||||
paypal.WebhookField{
|
||||
Operation: "replace",
|
||||
Path: "/event_types",
|
||||
Value: []interface{}{
|
||||
map[string]interface{}{
|
||||
"name": "PAYMENT.SALE.REFUNDED",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Get a registered webhook
|
||||
c.GetWebhook("WebhookID")
|
||||
|
||||
// Delete a webhook
|
||||
c.DeleteWebhook("WebhookID")
|
||||
|
||||
// List registered webhooks
|
||||
c.ListWebhooks(paypal.AncorTypeApplication)
|
||||
|
||||
```
|
||||
|
||||
### How to Contribute
|
||||
|
||||
* Fork a repository
|
||||
|
|
|
@ -132,3 +132,85 @@ func TestPatchCreditCard(t *testing.T) {
|
|||
t.Errorf("Error is expected for empty update info")
|
||||
}
|
||||
}
|
||||
|
||||
// Creates, gets, and deletes single webhook
|
||||
func TestCreateAndGetWebhook(t *testing.T) {
|
||||
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
|
||||
c.GetAccessToken()
|
||||
|
||||
payload := &CreateWebhookRequest{
|
||||
URL: "https://example.com/paypal_webhooks",
|
||||
EventTypes: []WebhookEventType{
|
||||
WebhookEventType{
|
||||
Name: "PAYMENT.AUTHORIZATION.CREATED",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
createdWebhook, err := c.CreateWebhook(payload)
|
||||
if err != nil {
|
||||
t.Errorf("Webhook couldn't be created, error %v", err)
|
||||
}
|
||||
|
||||
_, err = c.GetWebhook(createdWebhook.ID)
|
||||
if err != nil {
|
||||
t.Errorf("An error occurred while getting webhook, error %v", err)
|
||||
}
|
||||
|
||||
err = c.DeleteWebhook(createdWebhook.ID)
|
||||
if err != nil {
|
||||
t.Errorf("An error occurred while webhooks deletion, error %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Creates, updates, and deletes single webhook
|
||||
func TestCreateAndUpdateWebhook(t *testing.T) {
|
||||
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
|
||||
c.GetAccessToken()
|
||||
|
||||
creationPayload := &CreateWebhookRequest{
|
||||
URL: "https://example.com/paypal_webhooks",
|
||||
EventTypes: []WebhookEventType{
|
||||
WebhookEventType{
|
||||
Name: "PAYMENT.AUTHORIZATION.CREATED",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
createdWebhook, err := c.CreateWebhook(creationPayload)
|
||||
if err != nil {
|
||||
t.Errorf("Webhook couldn't be created, error %v", err)
|
||||
}
|
||||
|
||||
updatePayload := []WebhookField{
|
||||
WebhookField{
|
||||
Operation: "replace",
|
||||
Path: "/event_types",
|
||||
Value: []interface{}{
|
||||
map[string]interface{}{
|
||||
"name": "PAYMENT.SALE.REFUNDED",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err = c.UpdateWebhook(createdWebhook.ID, updatePayload)
|
||||
if err != nil {
|
||||
t.Errorf("Couldn't update webhook, error %v", err)
|
||||
}
|
||||
|
||||
err = c.DeleteWebhook(createdWebhook.ID)
|
||||
if err != nil {
|
||||
t.Errorf("An error occurred while webhooks deletion, error %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListWebhooks(t *testing.T) {
|
||||
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
|
||||
c.GetAccessToken()
|
||||
|
||||
_, err := c.ListWebhooks(AncorTypeApplication)
|
||||
if err != nil {
|
||||
t.Errorf("Cannot registered list webhooks, error %v", err)
|
||||
}
|
||||
}
|
||||
|
|
37
types.go
37
types.go
|
@ -124,6 +124,11 @@ const (
|
|||
LinkRelActionURL string = "action_url"
|
||||
)
|
||||
|
||||
const (
|
||||
AncorTypeApplication string = "APPLICATION"
|
||||
AncorTypeAccount string = "ACCOUNT"
|
||||
)
|
||||
|
||||
type (
|
||||
// JSONTime overrides MarshalJson method to format in ISO8601
|
||||
JSONTime time.Time
|
||||
|
@ -963,10 +968,20 @@ type (
|
|||
UserAction string `json:"user_action,omitempty"`
|
||||
}
|
||||
|
||||
// VerifyWebhookResponse struct
|
||||
VerifyWebhookResponse struct {
|
||||
VerificationStatus string `json:"verification_status,omitempty"`
|
||||
}
|
||||
|
||||
// Webhook strunct
|
||||
Webhook struct {
|
||||
ID string `json:"id"`
|
||||
URL string `json:"url"`
|
||||
EventTypes []WebhookEventType `json:"event_types"`
|
||||
Links []Link `json:"links"`
|
||||
}
|
||||
|
||||
// WebhookEvent struct
|
||||
WebhookEvent struct {
|
||||
ID string `json:"id"`
|
||||
CreateTime time.Time `json:"create_time"`
|
||||
|
@ -979,6 +994,28 @@ type (
|
|||
ResourceVersion string `json:"resource_version,omitempty"`
|
||||
}
|
||||
|
||||
// WebhookEventType struct
|
||||
WebhookEventType struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// CreateWebhookRequest struct
|
||||
CreateWebhookRequest struct {
|
||||
URL string `json:"url"`
|
||||
EventTypes []WebhookEventType `json:"event_types"`
|
||||
}
|
||||
|
||||
ListWebhookResponse struct {
|
||||
Webhooks []Webhook `json:"webhooks"`
|
||||
}
|
||||
|
||||
WebhookField struct {
|
||||
Operation string `json:"op"`
|
||||
Path string `json:"path"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
Resource struct {
|
||||
// Payment Resource type
|
||||
ID string `json:"id,omitempty"`
|
||||
|
|
70
webhooks.go
70
webhooks.go
|
@ -8,6 +8,76 @@ import (
|
|||
"net/http"
|
||||
)
|
||||
|
||||
// CreateWebhook - Subscribes your webhook listener to events.
|
||||
// Endpoint: POST /v1/notifications/webhooks
|
||||
func (c *Client) CreateWebhook(createWebhookRequest *CreateWebhookRequest) (*Webhook, error) {
|
||||
req, err := c.NewRequest(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(webhookID string) (*Webhook, error) {
|
||||
req, err := c.NewRequest(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(webhookID string, fields []WebhookField) (*Webhook, error) {
|
||||
req, err := c.NewRequest(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(anchorType string) (*ListWebhookResponse, error) {
|
||||
if len(anchorType) == 0 {
|
||||
anchorType = AncorTypeApplication
|
||||
}
|
||||
req, err := c.NewRequest(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(webhookID string) error {
|
||||
req, err := c.NewRequest(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(httpReq *http.Request, webhookID string) (*VerifyWebhookResponse, error) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user