Skip to content

Commit

Permalink
Merge 2884bc0 into 7bbd049
Browse files Browse the repository at this point in the history
  • Loading branch information
kbroderick committed Jan 25, 2021
2 parents 7bbd049 + 2884bc0 commit 01946fa
Show file tree
Hide file tree
Showing 25 changed files with 725 additions and 58 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -10,5 +10,6 @@ This is in development, currently the following parts of the API are working:
- Billing Plans
- Billing Agreements
- Payments
- Payouts

These work fine and I am using them in production, they have test coverage. Check out the docs :)
32 changes: 32 additions & 0 deletions fixture/custom_cassettes/payouts_cancel.json
@@ -0,0 +1,32 @@
[
{
"request":
{
"body": "",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer ACCESS-TOKEN-HERE"
},
"method": "post",
"options": [],
"request_body": "",
"url": "https://api.sandbox.paypal.com/v1/payments/payouts-item/5KUDKLF8SDC7S/cancel"
},
"response":
{
"body": "{\"payout_item_id\":\"5KUDKLF8SDC7S\",\"transaction_id\":\"1DG93452WK758815H\",\"activity_id\":\"0E158638XS0329101\",\"transaction_status\":\"RETURNED\",\"payout_item_fee\":{\"currency\":\"USD\",\"value\":\"0.35\"},\"payout_batch_id\":\"CQMWKDQF5GFLL\",\"sender_batch_id\":\"Payouts_2018_100006\",\"payout_item\":{\"recipient_type\":\"EMAIL\",\"amount\":{\"value\":\"9.87\",\"currency\":\"USD\"},\"note\":\"Thanks for your patronage!\",\"receiver\":\"receiver@example.com\",\"sender_item_id\":\"14Feb_234\"},\"time_processed\":\"2018-01-27T10:17:41Z\",\"errors\":{\"name\":\"RECEIVER_UNREGISTERED\",\"message\":\"Receiver is unregistered\",\"information_link\":\"https:\/\/developer.paypal.com\/docs\/api\/payments.payouts-batch#errors\"},\"links\":[{\"rel\":\"self\",\"href\":\"https:\/\/api.sandbox.paypal.com\/v1\/payments\/payouts-item\/5KUDKLF8SDC7S\",\"method\":\"GET\"},{\"rel\":\"batch\",\"href\":\"https:\/\/api.sandbox.paypal.com\/v1\/payments\/payouts\/CQMWKDQF5GFLL\",\"method\":\"GET\"}]}",
"headers": {
"Date": "Tue, 09 May 2017 02:41:25 GMT",
"Server": "Apache",
"Content-Language": "*",
"Vary": "Authorization",
"Content-Length": "669",
"Connection": "close",
"Content-Type": "application/json"
},
"status_code": 200,
"type": "ok"
}

}
]
32 changes: 32 additions & 0 deletions fixture/custom_cassettes/payouts_cancel_already_claimed.json
@@ -0,0 +1,32 @@
[
{
"request":
{
"body": "",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer ACCESS-TOKEN-HERE"
},
"method": "post",
"options": [],
"request_body": "{}",
"url": "https://api.sandbox.paypal.com/v1/payments/payouts-item/YYKMVR2AVSVZ4/cancel"
},
"response":
{
"body": "{\"name\":\"ITEM_INCORRECT_STATUS\",\"message\":\"Only items in Unclaimed status can be cancelled.\",\"debug_id\":\"49e81dfa52aaf\",\"information_link\":\"https:\/\/developer.paypal.com\/docs\/api\/payments.payouts-batch\/#errors\",\"links\":[]}",
"headers": {
"Date": "Tue, 09 May 2017 02:41:25 GMT",
"Server": "Apache",
"Content-Language": "*",
"Vary": "Authorization",
"Content-Length": "669",
"Connection": "close",
"Content-Type": "application/json"
},
"status_code": 400,
"type": "ok"
}

}
]
32 changes: 32 additions & 0 deletions fixture/custom_cassettes/payouts_cancel_notfound.json
@@ -0,0 +1,32 @@
[
{
"request":
{
"body": "",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer ACCESS-TOKEN-HERE"
},
"method": "post",
"options": [],
"request_body": "",
"url": "https://api.sandbox.paypal.com/v1/payments/payouts-item/DOESNTEXIST/cancel"
},
"response":
{
"body": "{\"name\":\"INVALID_RESOURCE_ID\",\"message\":\"The requested resource ID was not found\",\"debug_id\":\"415e0994fb40b\",\"information_link\":\"https:\/\/developer.paypal.com\/docs\/api\/payments.payouts-batch\/#errors\",\"details\":[],\"links\":[]}",
"headers": {
"Date": "Tue, 09 May 2017 02:41:25 GMT",
"Server": "Apache",
"Content-Language": "*",
"Vary": "Authorization",
"Content-Length": "669",
"Connection": "close",
"Content-Type": "application/json"
},
"status_code": 404,
"type": "ok"
}

}
]
34 changes: 34 additions & 0 deletions fixture/custom_cassettes/payouts_create_batch.json
@@ -0,0 +1,34 @@
[
{
"request":
{
"body": "{\"sender_batch_header\":{\"sender_batch_id\":\"Payouts_2018_100007\",\"email_subject\":\"You have a payout!\",\"email_message\":\"You have received a payout! Thanks for using our service!\"},\"items\":[{\"recipient_type\":\"EMAIL\",\"amount\":{\"value\":\"9.87\",\"currency\":\"USD\"},\"note\":\"Thanks for your patronage!\",\"sender_item_id\":\"201403140001\",\"receiver\":\"receiver@example.com\",\"alternate_notification_method\":{\"phone\":{\"country_code\":\"91\",\"national_number\":\"9999988888\"}},\"notification_language\":\"fr-FR\"},{\"recipient_type\":\"PHONE\",\"amount\":{\"value\":\"112.34\",\"currency\":\"USD\"},\"note\":\"Thanks for your support!\",\"sender_item_id\":\"201403140002\",\"receiver\":\"91-734-234-1234\"},{\"recipient_type\":\"PAYPAL_ID\",\"amount\":{\"value\":\"5.32\",\"currency\":\"USD\"},\"note\":\"Thanks for your patronage!\",\"sender_item_id\":\"201403140003\",\"receiver\":\"G83JXTJ5EHCQ2\"}]}",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer Access-Token",
"PayPal-Partner-Attribution-Id": "bn1234",
"PayPal-Request-Id": "idempotent1234"
},
"method": "post",
"options": [],
"request_body": "",
"url": "https://api.sandbox.paypal.com/v1/payments/payouts"
},
"response":
{
"body": "{\"batch_header\":{\"sender_batch_header\":{\"sender_batch_id\":\"Payouts_2018_100008\",\"email_subject\":\"You have a payout!\",\"email_message\":\"You have received a payout! Thanks for using our service!\"},\"payout_batch_id\":\"5UXD2E8A7EBQJ\",\"batch_status\":\"PENDING\"}}",
"headers": {
"Date": "Tue, 09 May 2017 02:41:25 GMT",
"Server": "Apache",
"Content-Language": "*",
"Vary": "Authorization",
"Content-Length": "257",
"Connection": "close",
"Content-Type": "application/json"
},
"status_code": 201,
"type": "ok"
}

}
]
29 changes: 29 additions & 0 deletions fixture/custom_cassettes/payouts_create_payout_error.json
@@ -0,0 +1,29 @@
[
{
"request": {
"body": "{\"batch_header\": {}, \"items\":{} }",
"headers": {
"Authorization": "***",
"Content-Type": "application/json"
},
"method": "post",
"options": [],
"request_body": "",
"url": "https://api.sandbox.paypal.com/v1/payments/payouts"
},
"response": {
"body": "{\"name\":\"VALIDATION_ERROR\",\"details\":[{\"field\":\"batch_header\",\"issue\":\"Value is invalid.\"}],\"message\":\"Invalid request. See details.\",\"information_link\":\"https://developer.paypal.com/webapps/developer/docs/api/#VALIDATION_ERROR\",\"debug_id\":\"9a24956b454c4\"}",
"headers": {
"Date": "Tue, 09 May 2017 02:44:29 GMT",
"Server": "Apache",
"Content-Language": "*",
"Connection": "close",
"Vary": "Authorization",
"Content-Length": "251",
"Content-Type": "application/json"
},
"status_code": 400,
"type": "ok"
}
}
]
32 changes: 32 additions & 0 deletions fixture/custom_cassettes/payouts_get_payout.json
@@ -0,0 +1,32 @@
[
{
"request":
{
"body": "",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer ACCESS-TOKEN-HERE"
},
"method": "get",
"options": [],
"request_body": "",
"url": "https://api.sandbox.paypal.com/v1/payments/payouts-item/8AELMXH8UB2P8"
},
"response":
{
"body": "{\"payout_item_id\":\"8AELMXH8UB2P8\",\"transaction_id\":\"0C413693MN970190K\",\"activity_id\":\"0E158638XS0329106\",\"transaction_status\":\"SUCCESS\",\"payout_item_fee\":{\"currency\":\"USD\",\"value\":\"0.35\"},\"payout_batch_id\":\"Q8KVJG9TZTNN4\",\"payout_item\":{\"amount\":{\"value\":\"9.87\",\"currency\":\"USD\"},\"recipient_type\":\"EMAIL\",\"note\":\"Thanks for your patronage!\",\"receiver\":\"receiver@example.com\",\"sender_item_id\":\"14Feb_234\"},\"time_processed\":\"2018-01-27T10:17:41Z\",\"links\":[{\"rel\":\"self\",\"href\":\"https:\/\/api.sandbox.paypal.com\/v1\/payments\/payouts-item\/8AELMXH8UB2P8\",\"method\":\"GET\"},{\"href\":\"https:\/\/api.sandbox.paypal.com\/v1\/payments\/payouts\/Q8KVJG9TZTNN4\",\"rel\":\"batch\",\"method\":\"GET\"}]}",
"headers": {
"Date": "Tue, 09 May 2017 02:41:25 GMT",
"Server": "Apache",
"Content-Language": "*",
"Vary": "Authorization",
"Content-Length": "669",
"Connection": "close",
"Content-Type": "application/json"
},
"status_code": 200,
"type": "ok"
}

}
]
32 changes: 32 additions & 0 deletions fixture/custom_cassettes/payouts_get_payout_error.json
@@ -0,0 +1,32 @@
[
{
"request":
{
"body": "",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer ACCESS-TOKEN-HERE"
},
"method": "get",
"options": [],
"request_body": "",
"url": "https://api.sandbox.paypal.com/v1/payments/payouts-item/DOESNTEXIST"
},
"response":
{
"body": {"name":"INVALID_RESOURCE_ID","message":"The requested resource ID was not found","debug_id":"3dbf652547e56","information_link":"https://developer.paypal.com/docs/api/payments.payouts-batch/#errors","details":[],"links":[]},
"headers": {
"Date": "Tue, 09 May 2017 02:41:25 GMT",
"Server": "Apache",
"Content-Language": "*",
"Vary": "Authorization",
"Content-Length": "669",
"Connection": "close",
"Content-Type": "application/json"
},
"status_code": 404,
"type": "ok"
}

}
]
32 changes: 32 additions & 0 deletions fixture/custom_cassettes/payouts_get_payouts_batch.json
@@ -0,0 +1,32 @@
[
{
"request":
{
"body": "",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer Access-Token"
},
"method": "get",
"options": [],
"request_body": "",
"url": "https://api.sandbox.paypal.com/v1/payments/payouts/FYXMPQTX4JC9N"
},
"response":
{
"body": "{\"batch_header\":{\"payout_batch_id\":\"FYXMPQTX4JC9N\",\"batch_status\":\"PROCESSING\",\"time_created\":\"2014-01-27T10:17:00Z\",\"time_completed\":\"2014-01-27T11:17:39.00Z\",\"sender_batch_header\":{\"sender_batch_id\":\"Payouts_2018_100009\",\"email_subject\":\"You have a payout!\"},\"amount\":{\"value\":\"438.35\",\"currency\":\"USD\"},\"fees\":{\"value\":\"5.84\",\"currency\":\"USD\"}},\"items\":[{\"payout_item_id\":\"DUCD8GC3VUKVE\",\"transaction_id\":\"6KA23440H1057442S\",\"transaction_status\":\"SUCCESS\",\"payout_batch_id\":\"FYXMPQTX4JC9N\",\"payout_item_fee\":{\"currency\":\"USD\",\"value\":\"1.00\"},\"payout_item\":{\"recipient_type\":\"EMAIL\",\"amount\":{\"value\":\"65.24\",\"currency\":\"USD\"},\"note\":\"Thanks for your patronage!\",\"receiver\":\"receiver@example.com\",\"sender_item_id\":\"14Feb_978\"},\"time_processed\":\"2014-01-27T10:18:32Z\"},{\"payout_item_id\":\"LGMEPRKTK7FQA\",\"transaction_id\":\"8K128187J1102003K\",\"transaction_status\":\"SUCCESS\",\"payout_batch_id\":\"FYXMPQTX4JC9N\",\"payout_item_fee\":{\"currency\":\"USD\",\"value\":\"1.00\"},\"payout_item\":{\"recipient_type\":\"EMAIL\",\"amount\":{\"value\":\"59.87\",\"currency\":\"USD\"},\"note\":\"Thanks for your patronage!\",\"receiver\":\"receiver2@example.com\",\"sender_item_id\":\"14Feb_321\"},\"time_processed\":\"2014-01-27T10:18:15Z\"},{\"payout_item_id\":\"BQ8GT9VG64EFS\",\"transaction_id\":\"57382391EC1682714\",\"transaction_status\":\"SUCCESS\",\"payout_batch_id\":\"FYXMPQTX4JC9N\",\"payout_item_fee\":{\"currency\":\"USD\",\"value\":\"1.00\"},\"payout_item\":{\"recipient_type\":\"EMAIL\",\"amount\":{\"value\":\"59.87\",\"currency\":\"USD\"},\"note\":\"Thanks for your patronage!\",\"receiver\":\"receiver3@example.com\",\"sender_item_id\":\"14Feb_239\"},\"time_processed\":\"2014-01-27T10:17:15Z\"},{\"payout_item_id\":\"LHKZN4VT93L2Q\",\"transaction_id\":\"1LG71547D1353984N\",\"transaction_status\":\"SUCCESS\",\"payout_batch_id\":\"FYXMPQTX4JC9N\",\"payout_item_fee\":{\"value\":\"USD\",\"currency\":\"0.75\"},\"payout_item\":{\"recipient_type\":\"EMAIL\",\"amount\":{\"value\":\"19.87\",\"currency\":\"USD\"},\"note\":\"Thanks for your patronage!\",\"receiver\":\"receiver4@example.com\",\"sender_item_id\":\"14Feb_235\"},\"time_processed\":\"2014-01-27T10:17:25Z\"},{\"payout_item_id\":\"4ZF3VZHHTQJG6\",\"transaction_id\":\"4BD48613EX3256543\",\"transaction_status\":\"SUCCESS\",\"payout_batch_id\":\"FYXMPQTX4JC9N\",\"payout_item_fee\":{\"currency\":\"USD\",\"value\":\"0.75\"},\"payout_item\":{\"recipient_type\":\"EMAIL\",\"amount\":{\"value\":\"9.87\",\"currency\":\"USD\"},\"note\":\"Thanks for your patronage!\",\"receiver\":\"receiver@example.com\",\"sender_item_id\":\"14Feb_234\"},\"time_processed\":\"2014-01-27T10:17:37Z\"},{\"payout_item_id\":\"DTCJCQ6LMH8JQ\",\"transaction_id\":\"25F63571CL9929422\",\"transaction_status\":\"SUCCESS\",\"payout_item_fee\":{\"currency\":\"USD\",\"value\":\"2.35\"},\"payout_batch_id\":\"FYXMPQTX4JC9N\",\"payout_item\":{\"recipient_type\":\"PHONE\",\"amount\":{\"value\":\"112.34\",\"currency\":\"USD\"},\"note\":\"Thanks for your support!\",\"receiver\":\"91-734-234-1234\",\"sender_item_id\":\"14Feb_235\"},\"time_processed\":\"2014-01-27T10:17:52Z\"},{\"payout_item_id\":\"GSBDQHUAUD44A\",\"transaction_id\":\"53R03517P98080414\",\"transaction_status\":\"SUCCESS\",\"payout_batch_id\":\"FYXMPQTX4JC9N\",\"payout_item_fee\":{\"currency\":\"USD\",\"value\":\"2.5\"},\"payout_item\":{\"recipient_type\":\"PHONE\",\"amount\":{\"value\":\"5.32\",\"currency\":\"USD\"},\"note\":\"Thanks for your patronage!\",\"receiver\":\"408X234-1234\",\"sender_item_id\":\"14Feb_235\"},\"time_processed\":\"2014-01-27T10:17:41Z\"}],\"links\":[{\"rel\":\"self\",\"href\":\"https:\/\/api.sandbox.paypal.com\/v1\/payments\/payouts\/FYXMPQTX4JC9N?page_size=1000&page=1\",\"method\":\"GET\"}]}",
"headers": {
"Date": "Tue, 09 May 2017 02:41:25 GMT",
"Server": "Apache",
"Content-Language": "*",
"Vary": "Authorization",
"Content-Length": "3371",
"Connection": "close",
"Content-Type": "application/json"
},
"status_code": 200,
"type": "ok"
}

}
]
32 changes: 32 additions & 0 deletions fixture/custom_cassettes/payouts_get_payouts_batch_error.json
@@ -0,0 +1,32 @@
[
{
"request":
{
"body": "",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer Access-Token"
},
"method": "get",
"options": [],
"request_body": "",
"url": "https://api.sandbox.paypal.com/v1/payments/payouts/DOESNTEXIST"
},
"response":
{
"body": "{\"name\":\"INVALID_RESOURCE_ID\",\"message\":\"The requested resource ID was not found\",\"debug_id\":\"1b1498ce1b50a\",\"information_link\":\"https:\/\/developer.paypal.com\/docs\/api\/payments.payouts-batch\/#errors\",\"details\":[],\"links\":[]}",
"headers": {
"Date": "Tue, 09 May 2017 02:41:25 GMT",
"Server": "Apache",
"Content-Language": "*",
"Vary": "Authorization",
"Content-Length": "257",
"Connection": "close",
"Content-Type": "application/json"
},
"status_code": 404,
"type": "ok"
}

}
]
1 change: 1 addition & 0 deletions fixture/vcr_cassettes/payments_create_payout_error.json
@@ -0,0 +1 @@
[]
1 change: 1 addition & 0 deletions fixture/vcr_cassettes/payouts_cancel_already_claimed.json
@@ -0,0 +1 @@
[]
1 change: 1 addition & 0 deletions fixture/vcr_cassettes/payouts_create_batch.json
@@ -0,0 +1 @@
[]
8 changes: 4 additions & 4 deletions lib/api.ex
Expand Up @@ -22,7 +22,7 @@ defmodule PayPal.API do
{:ok, {"XXXXXXXXXXXXXX", 32000}}
"""
@spec get_oauth_token :: {atom, any}
@spec get_oauth_token :: {:error, :unauthorised | :bad_network} | {:ok, {binary, integer}}
def get_oauth_token do
headers = %{"Content-Type" => "application/x-www-form-urlencoded"}
options = [hackney: [basic_auth: {PayPal.Config.get.client_id, PayPal.Config.get.client_secret}]]
Expand Down Expand Up @@ -58,7 +58,7 @@ defmodule PayPal.API do
{:ok, {"XXXXXXXXXXXXXX", 32000}}
"""
@spec get(String.t) :: {atom, any}
@spec get(String.t) :: {:ok, map | :not_found | :no_content } | {:error, :unauthorised | :bad_network | any}
def get(url) do
case HTTPoison.get(base_url() <> url, headers()) do
{:ok, %{status_code: 401}} ->
Expand Down Expand Up @@ -97,7 +97,7 @@ defmodule PayPal.API do
{:ok, {"XXXXXXXXXXXXXX", 32000}}
"""
@spec post(String.t, map) :: {atom, any}
@spec post(String.t, map | list | nil) :: {:ok, map | :not_found | :no_content | nil} | {:error, :unauthorised | :bad_network | any}
def post(url, data) do
{:ok, data} = Poison.encode(data)
case HTTPoison.post(base_url() <> url, data, headers()) do
Expand Down Expand Up @@ -140,7 +140,7 @@ defmodule PayPal.API do
{:ok, {"XXXXXXXXXXXXXX", 32000}}
"""
@spec patch(String.t, map) :: {atom, any}
@spec patch(String.t, map | list) :: {:ok, map | nil | :not_found | :no_content} | {:error, :unauthorised | :bad_network | any}
def patch(url, data) do
{:ok, data} = Poison.encode(data)
case HTTPoison.patch(base_url() <> url, data, headers()) do
Expand Down

0 comments on commit 01946fa

Please sign in to comment.