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***
|
* PATCH /v2/payments/billing-plans/***ID***
|
||||||
* POST /v2/payments/billing-agreements
|
* POST /v2/payments/billing-agreements
|
||||||
* POST /v2/payments/billing-agreements/***TOKEN***/agreement-execute
|
* 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
|
* POST /v1/notifications/verify-webhook-signature
|
||||||
|
|
||||||
### Missing endpoints
|
### Missing endpoints
|
||||||
|
@ -281,6 +286,42 @@ c.GetCreditCard("CARD-ID-123")
|
||||||
c.GetCreditCards(nil)
|
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
|
### How to Contribute
|
||||||
|
|
||||||
* Fork a repository
|
* Fork a repository
|
||||||
|
|
|
@ -132,3 +132,85 @@ func TestPatchCreditCard(t *testing.T) {
|
||||||
t.Errorf("Error is expected for empty update info")
|
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"
|
LinkRelActionURL string = "action_url"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AncorTypeApplication string = "APPLICATION"
|
||||||
|
AncorTypeAccount string = "ACCOUNT"
|
||||||
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// JSONTime overrides MarshalJson method to format in ISO8601
|
// JSONTime overrides MarshalJson method to format in ISO8601
|
||||||
JSONTime time.Time
|
JSONTime time.Time
|
||||||
|
@ -963,10 +968,20 @@ type (
|
||||||
UserAction string `json:"user_action,omitempty"`
|
UserAction string `json:"user_action,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VerifyWebhookResponse struct
|
||||||
VerifyWebhookResponse struct {
|
VerifyWebhookResponse struct {
|
||||||
VerificationStatus string `json:"verification_status,omitempty"`
|
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 {
|
WebhookEvent struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
CreateTime time.Time `json:"create_time"`
|
CreateTime time.Time `json:"create_time"`
|
||||||
|
@ -979,6 +994,28 @@ type (
|
||||||
ResourceVersion string `json:"resource_version,omitempty"`
|
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 {
|
Resource struct {
|
||||||
// Payment Resource type
|
// Payment Resource type
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
|
|
70
webhooks.go
70
webhooks.go
|
@ -8,6 +8,76 @@ import (
|
||||||
"net/http"
|
"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.
|
// VerifyWebhookSignature - Use this to verify the signature of a webhook recieved from paypal.
|
||||||
// Endpoint: POST /v1/notifications/verify-webhook-signature
|
// Endpoint: POST /v1/notifications/verify-webhook-signature
|
||||||
func (c *Client) VerifyWebhookSignature(httpReq *http.Request, webhookID string) (*VerifyWebhookResponse, error) {
|
func (c *Client) VerifyWebhookSignature(httpReq *http.Request, webhookID string) (*VerifyWebhookResponse, error) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user