From c8530e87d3490a84bc2820156627c3cb81a1f240 Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Mon, 6 Oct 2014 11:44:55 -0600 Subject: [PATCH 01/38] Add Account spec --- fixtures/_models/account.json | 59 +++++++++++++++++++++++++++++++++++ fixtures/accounts.json | 51 ++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 fixtures/_models/account.json create mode 100644 fixtures/accounts.json diff --git a/fixtures/_models/account.json b/fixtures/_models/account.json new file mode 100644 index 0000000..ec7346f --- /dev/null +++ b/fixtures/_models/account.json @@ -0,0 +1,59 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "The redeemable balance of a customer is represented as a financial instrument just like a Card or Bank Account.", + "type": "object", + "properties": { + "id": { + "type": "string", + "pattern": "(AT)[a-zA-Z0-9]{16,32}" + }, + "href": { + "type": "string", + "format": "uri" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "balance": { + "type": "integer", + "minimum": 0 + }, + "currency": { + "type": "string", + "enum": [ + "USD" + ] + }, + "meta": { + "type": "object" + }, + "links": { + "type": "object", + "properties": { + "customer": { + "type": "string", + "pattern": "(CU|AC)[a-zA-Z0-9]{16,32}" + } + }, + "additionalProperties": false, + "required": [ + "customer" + ] + } + }, + "required": [ + "id", + "href", + "created_at", + "updated_at", + "balance", + "currency", + "meta", + "links" + ] +} \ No newline at end of file diff --git a/fixtures/accounts.json b/fixtures/accounts.json new file mode 100644 index 0000000..65fe471 --- /dev/null +++ b/fixtures/accounts.json @@ -0,0 +1,51 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "links": { + "type": "object", + "properties": { + "accounts.customer": { + "type": "string", + "format": "uri", + "pattern": "/customers/{accounts.customer}" + }, + "accounts.credits": { + "type": "string", + "format": "uri", + "pattern": "/accounts/{accounts.id}/credits" + }, + "accounts.debits": { + "type": "string", + "format": "uri", + "pattern": "/accounts/{accounts.id}/debits" + }, + "accounts.transfers": { + "type": "string", + "format": "uri", + "pattern": "/accounts/{accounts.id}/transfers" + } + }, + "additionalProperties": false, + "required": [ + "accounts.customer", + "accounts.credits", + "accounts.debits" + ] + }, + "meta": { + "type": "object" + }, + "accounts": { + "items": { + "$ref": "_models/account.json" + }, + "type": "array", + "minItems": 1, + "uniqueItems": true + } + }, + "required": [ + "accounts" + ] +} \ No newline at end of file From 29279bd9ad4919b68de88a5b5677ea3f0ce1990f Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Mon, 6 Oct 2014 11:45:41 -0600 Subject: [PATCH 02/38] Add sweep_account link to BankAccount resource --- fixtures/_models/bank_account.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fixtures/_models/bank_account.json b/fixtures/_models/bank_account.json index 5e0e8a7..350d65b 100644 --- a/fixtures/_models/bank_account.json +++ b/fixtures/_models/bank_account.json @@ -84,6 +84,14 @@ "string" ], "pattern": "BZ[a-zA-Z0-9]{16,32}" + }, + "sweep_account": { + "description": "A funding instrument representing a sweep account used for bulk credits", + "type": [ + "null", + "string" + ], + "pattern": "(AT)[a-zA-Z0-9]{16,32}" } }, "required": [ From 8471295d2094afa265a4f5fcf9e8f3026a9b3856 Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Mon, 6 Oct 2014 11:46:11 -0600 Subject: [PATCH 03/38] Add bulk credit to sweep account feature --- features/credits.feature | 47 +++++++++++++++++++++++++++++ features/step_definitions/orders.rb | 20 ++++++++++++ 2 files changed, 67 insertions(+) diff --git a/features/credits.feature b/features/credits.feature index 7ffe1bd..29f16e9 100644 --- a/features/credits.feature +++ b/features/credits.feature @@ -124,3 +124,50 @@ Feature: Credits "category_code": "no-funding-destination" } """ + + + Scenario: Bulk credit to sweep account + Given I have a merchant with 2 orders with debits + When I POST to /bank_accounts/:bank_account_id/sweep_account with the body: + """ + { + "credits": [{ + "amount": 1234, + "order": "/orders/:order_id_1", + "appears_on_statement_as": "Payout group A" + }] + } + """ + Then I should get a 201 Created status code + And the response is valid according to the "credits" schema + + When I make a GET request to /bank_accounts/:bank_account_id/sweep_account + Then I should get a 200 OK status code + And the fields on this error match: + """ + { + "balance": 1234 + } + """ + + When I POST to /bank_accounts/:bank_account_id/sweep_account with the body: + """ + { + "credits": [{ + "amount": 1234, + "order": "/orders/:order_id_2", + "appears_on_statement_as": "Payout group B" + }] + } + """ + Then I should get a 201 Created status code + And the response is valid according to the "credits" schema + + When I make a GET request to /bank_accounts/:bank_account_id/sweep_account + Then I should get a 200 OK status code + And the fields on this error match: + """ + { + "balance": 2468 + } + """ diff --git a/features/step_definitions/orders.rb b/features/step_definitions/orders.rb index 96d342a..84e584e 100644 --- a/features/step_definitions/orders.rb +++ b/features/step_definitions/orders.rb @@ -55,4 +55,24 @@ order: @order_id }) @client.add_hydrate :card_hold_id, @client['id'] +end + + +Given(/^I have a merchant with (\d) orders with debits$/) do |num| + step 'I have created a customer' + @client.post('/customers', {}) + @merchant_id = @client['id'] + @client.add_hydrate :merchant_id, @merchant_id + step 'I have tokenized a bank account and associated with the merchant' + num.to_i.times do |i| + @client.post("/customers/#{@merchant_id}/orders", {}) + order_id = @client['id'] + @client.add_hydrate :order_id, order_id + @client.post("/cards/#{@card_id}/debits", { + amount: 12345, + order: order_id + }) + @client.add_hydrate :debit_id, @merchant_id + instance_variable_set("@order_id_#{i + 1}", order_id) + end end \ No newline at end of file From f42089a3db3861337efaaba0ee49f27aeef89674 Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Mon, 6 Oct 2014 11:57:40 -0600 Subject: [PATCH 04/38] Remove transfers link --- fixtures/accounts.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/fixtures/accounts.json b/fixtures/accounts.json index 65fe471..51f3bd8 100644 --- a/fixtures/accounts.json +++ b/fixtures/accounts.json @@ -19,11 +19,6 @@ "type": "string", "format": "uri", "pattern": "/accounts/{accounts.id}/debits" - }, - "accounts.transfers": { - "type": "string", - "format": "uri", - "pattern": "/accounts/{accounts.id}/transfers" } }, "additionalProperties": false, From 172a527e770a9686b81b631e464faf541b337914 Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Thu, 16 Oct 2014 17:50:13 -0600 Subject: [PATCH 05/38] Spec Account and Settlement resources. Update bulk credit feature. --- features/accounts.feature | 36 ++++++++ features/credits.feature | 18 ++-- features/settlements.feature | 108 +++++++++++++++++++++++ features/step_definitions/account.rb | 8 ++ features/step_definitions/customers.rb | 1 + features/step_definitions/settlements.rb | 14 +++ fixtures/_models/account.json | 4 +- fixtures/_models/credit.json | 2 +- fixtures/_models/customer.json | 9 ++ fixtures/_models/reversal.json | 2 +- fixtures/_models/settlement.json | 93 +++++++++++++++++++ fixtures/accounts.json | 8 +- fixtures/credits.json | 6 ++ fixtures/customers.json | 6 ++ fixtures/reversals.json | 6 ++ fixtures/settlements.json | 44 +++++++++ 16 files changed, 351 insertions(+), 14 deletions(-) create mode 100644 features/accounts.feature create mode 100644 features/settlements.feature create mode 100644 features/step_definitions/account.rb create mode 100644 features/step_definitions/settlements.rb create mode 100644 fixtures/_models/settlement.json create mode 100644 fixtures/settlements.json diff --git a/features/accounts.feature b/features/accounts.feature new file mode 100644 index 0000000..bf38b58 --- /dev/null +++ b/features/accounts.feature @@ -0,0 +1,36 @@ +Feature: Accounts + Accounts are a way to have a store of some kind of value. + + Scenario: List accounts + Given I have created a customer + When I GET to /accounts + Then I should get a 200 OK status code + And the response is valid according to the "accounts" schema + + Scenario: Retrieving accounts for a customer + Given I have created a customer + When I GET to /customers/:customer_id/accounts + Then I should get a 200 OK status code + And the response is valid according to the "accounts" schema + And the fields on these credits match: + """ + { + "links": { + "customer": ":customer_id" + } + } + """ + + Scenario: Credit a customer deposit account + Given I have an order with a debit + When I POST to /accounts/:customer_deposit_account_id/credits + """ + { + "credits": [{ + "amount": 234, + "order": "/orders/:order_id" + }] + } + """ + Then I should get a 201 Created status code + And the response is valid according to the "credits" schema \ No newline at end of file diff --git a/features/credits.feature b/features/credits.feature index 29f16e9..f4e4279 100644 --- a/features/credits.feature +++ b/features/credits.feature @@ -126,13 +126,13 @@ Feature: Credits """ - Scenario: Bulk credit to sweep account + Scenario: Bulk credit to a customer deposit account Given I have a merchant with 2 orders with debits - When I POST to /bank_accounts/:bank_account_id/sweep_account with the body: + When I POST to /accounts/:customer_deposit_account_id/credits with the body: """ { "credits": [{ - "amount": 1234, + "amount": 1000, "order": "/orders/:order_id_1", "appears_on_statement_as": "Payout group A" }] @@ -141,20 +141,20 @@ Feature: Credits Then I should get a 201 Created status code And the response is valid according to the "credits" schema - When I make a GET request to /bank_accounts/:bank_account_id/sweep_account + When I make a GET request to /accounts/:customer_deposit_account_id Then I should get a 200 OK status code And the fields on this error match: """ { - "balance": 1234 + "balance": 1000 } """ - When I POST to /bank_accounts/:bank_account_id/sweep_account with the body: + When I POST to /accounts/:customer_deposit_account_id/credits with the body: """ { "credits": [{ - "amount": 1234, + "amount": 1000, "order": "/orders/:order_id_2", "appears_on_statement_as": "Payout group B" }] @@ -163,11 +163,11 @@ Feature: Credits Then I should get a 201 Created status code And the response is valid according to the "credits" schema - When I make a GET request to /bank_accounts/:bank_account_id/sweep_account + When I make a GET request to /accounts/:customer_deposit_account_id/credits Then I should get a 200 OK status code And the fields on this error match: """ { - "balance": 2468 + "balance": 2000 } """ diff --git a/features/settlements.feature b/features/settlements.feature new file mode 100644 index 0000000..fb0f57e --- /dev/null +++ b/features/settlements.feature @@ -0,0 +1,108 @@ +@focus +Feature: Settlements + Settlement is the action of moving money out of an Account to a + bank account. + + Scenario: Create a settlement + Given I have an Account with sufficient funds + And I have tokenized a bank account + When I POST to /settlements with the body: + """ + { + "settlements": [{ + "destination": "/bank_accounts/:bank_account_id", + "appears_on_statement_as": "Settlement Oct", + "description": "Settlement for payouts from October" + }] + } + """ + Then I should get a 201 Created status code + And the response is valid according to the "settlements" schema + And the fields on this settlement match: + """ + { + "amount": "10000", + "appears_on_statement_as": "BAL*Settlement Oct", + "description": "Settlement for payouts from October", + "links": { + "destination": ":bank_account_id" + } + } + """ + + Scenario: List settlements + Given I have 2 settlements + When I GET to /settlements + Then I should get a 200 OK status code + And the response is valid according to the "settlements" schema + + Scenario: Retrieving settlements for a bank account + Given I have a bank account with a settlement + When I GET to /bank_accounts/:bank_account_id/settlements + Then I should get a 200 OK status code + And the response is valid according to the "settlements" schema + And the fields on these settlements match: + """ + { + "links": { + "destination": ":bank_account_id" + } + } + """ + + Scenario: Updating a settlement description + Given I have a bank account with a settlement + When I PUT to /settlements/:settlement_id with the body: + """ + { + "description": "A new settlement description" + } + """ + Then I should get a 200 OK status code + And the response is valid according to the "settlements" schema + And the fields on this settlement match: + """ + { + "description": "A new settlement description" + } + """ + + Scenario: Updating a settlement meta + Given I have a bank account with a settlement + When I PUT to /settlements/:settlement_id with the body: + """ + { + "meta": { + "reference_number": "546512" + } + } + """ + Then I should get a 200 OK status code + And the response is valid according to the "settlements" schema + And the fields on this settlement match: + """ + { + "meta": { + "reference_number": "546512" + } + } + """ + + Scenario: Creating a settlement without a funding destination leads to failure + When I POST to /settlements with the body: + """ + { + "settlements": [{ + "description": "Will this credit work? Nobody knows" + }] + } + """ + Then I should get a 409 status code + And the response is valid according to the "errors" schema + And the fields on this error match: + """ + { + "category_code": "no-funding-destination" + } + """ + diff --git a/features/step_definitions/account.rb b/features/step_definitions/account.rb new file mode 100644 index 0000000..91c7468 --- /dev/null +++ b/features/step_definitions/account.rb @@ -0,0 +1,8 @@ +Given(/^I have an Account with sufficient funds$/) do + step 'I have an order with a debit' + @client.post("/accounts/#{@customer_deposit_account_id}/credits", { + amount: 10000, + order: @order_id + }) + @client.add_hydrate :credit_id, @client['id'] +end \ No newline at end of file diff --git a/features/step_definitions/customers.rb b/features/step_definitions/customers.rb index a005d8d..0788130 100644 --- a/features/step_definitions/customers.rb +++ b/features/step_definitions/customers.rb @@ -11,6 +11,7 @@ ) @customer_id = @client['id'] @client.add_hydrate :customer_id, @customer_id + @client.add_hydrate :customer_deposit_account_id, @client['accounts']['deposit'] @customer_url = @client['customers']['href'] diff --git a/features/step_definitions/settlements.rb b/features/step_definitions/settlements.rb new file mode 100644 index 0000000..a82b2dc --- /dev/null +++ b/features/step_definitions/settlements.rb @@ -0,0 +1,14 @@ +Given(/^I have a bank account with a settlement$/) do + step 'I have an order with a debit' + step 'I have created a customer' + @client.post("/accounts/#{@customer_deposit_account_id}/credits", { + amount: 1234, + order: :order_id + }) + @settlement_id = @client['settlements']['id'] + @client.add_hydrate :settlement_id, @settlement_id +end + +Given(/^I have (\d) settlements$/) do + num.to_i.times { step 'I have a bank account with a settlement' } +end diff --git a/fixtures/_models/account.json b/fixtures/_models/account.json index ec7346f..c5878c8 100644 --- a/fixtures/_models/account.json +++ b/fixtures/_models/account.json @@ -5,7 +5,7 @@ "properties": { "id": { "type": "string", - "pattern": "(AT)[a-zA-Z0-9]{16,32}" + "pattern": "AT[a-zA-Z0-9]{16,32}" }, "href": { "type": "string", @@ -37,7 +37,7 @@ "properties": { "customer": { "type": "string", - "pattern": "(CU|AC)[a-zA-Z0-9]{16,32}" + "pattern": "CU[a-zA-Z0-9]{16,32}" } }, "additionalProperties": false, diff --git a/fixtures/_models/credit.json b/fixtures/_models/credit.json index 047099e..8a13f22 100644 --- a/fixtures/_models/credit.json +++ b/fixtures/_models/credit.json @@ -76,7 +76,7 @@ "destination": { "description": "The funding destination for this credit", "type": "string", - "pattern": "(CC|BA)[a-zA-Z0-9]{16,32}" + "pattern": "(CC|BA|AT)[a-zA-Z0-9]{16,32}" }, "order": { "description": "The order this credit is associated with", diff --git a/fixtures/_models/customer.json b/fixtures/_models/customer.json index f082c63..0eccbb8 100644 --- a/fixtures/_models/customer.json +++ b/fixtures/_models/customer.json @@ -98,6 +98,14 @@ "links": { "type": "object", "properties": { + "accounts": [ + { + "deposit_account": { + "type": "string", + "pattern": "(AT)[a-zA-Z0-9]{16,32}" + } + } + ], "source": { "type": [ "null", @@ -114,6 +122,7 @@ } }, "required": [ + "accounts", "source", "destination" ], diff --git a/fixtures/_models/reversal.json b/fixtures/_models/reversal.json index 1f0ad7f..8073b1f 100644 --- a/fixtures/_models/reversal.json +++ b/fixtures/_models/reversal.json @@ -68,7 +68,7 @@ "pattern": "CR[a-zA-Z0-9]{16,32}" }, "order": { - "description": "The order this credit is assocaited with", + "description": "The order this credit is associated with", "type": [ "null", "string" diff --git a/fixtures/_models/settlement.json b/fixtures/_models/settlement.json new file mode 100644 index 0000000..82e0f9b --- /dev/null +++ b/fixtures/_models/settlement.json @@ -0,0 +1,93 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "id": { + "type": "string", + "pattern": "(ST)[a-zA-Z0-9]{16,32}" + }, + "href": { + "type": "string", + "format": "uri" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "amount": { + "type": "integer", + "minimum": 0 + }, + "currency": { + "type": "string", + "enum": [ + "USD" + ] + }, + "appears_on_statement_as": { + "type": "string" + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "status": { + "$ref": "status.json" + }, + "failure_reason_code": { + "type": [ + "string", + "null" + ] + }, + "failure_reason": { + "type": [ + "string", + "null" + ] + }, + "meta": { + "$ref": "meta.json" + }, + "links": { + "type": "object", + "properties": { + "destination": { + "type": "string", + "pattern": "BA[a-zA-Z0-9]{16,32}" + }, + "account": { + "type": "string", + "pattern": "AT[a-zA-Z0-9]{16,32}" + } + }, + "required": [ + "destination", + "account" + ], + } + }, + "additionalProperties": false, + "required": [ + "id", + "href", + "created_at", + "updated_at", + "amount", + "currency", + "appears_on_statement_as", + "description", + "status", + "failure_reason_code", + "failure_reason", + "transaction_number", + "meta", + "links" + ] +} \ No newline at end of file diff --git a/fixtures/accounts.json b/fixtures/accounts.json index 51f3bd8..5e5a1a1 100644 --- a/fixtures/accounts.json +++ b/fixtures/accounts.json @@ -19,13 +19,19 @@ "type": "string", "format": "uri", "pattern": "/accounts/{accounts.id}/debits" + }, + "accounts.settlements": { + "type": "string", + "format": "uri", + "pattern": "/accounts/{accounts.id}/settlements" } }, "additionalProperties": false, "required": [ "accounts.customer", "accounts.credits", - "accounts.debits" + "accounts.debits", + "accounts.settlements" ] }, "meta": { diff --git a/fixtures/credits.json b/fixtures/credits.json index c2a3a73..517b687 100644 --- a/fixtures/credits.json +++ b/fixtures/credits.json @@ -25,6 +25,11 @@ "format": "uri", "pattern": "/resources/{credits.destination}" }, + "credits.account": { + "type": "string", + "format": "uri", + "pattern": "/accounts/{credits.account}" + }, "credits.events": { "type": "string", "format": "uri", @@ -36,6 +41,7 @@ "credits.customer", "credits.order", "credits.destination", + "credits.account", "credits.events" ] }, diff --git a/fixtures/customers.json b/fixtures/customers.json index 3e1e1fb..9a9823c 100644 --- a/fixtures/customers.json +++ b/fixtures/customers.json @@ -51,6 +51,11 @@ "format": "uri", "pattern": "/customers/{customers.id}/orders" }, + "customers.accounts": { + "type": "string", + "format": "uri", + "pattern": "/customers/{customers.id}/accounts" + }, "customers.source": { "type": "string", "format": "uri", @@ -71,6 +76,7 @@ "customers.refunds", "customers.reversals", "customers.orders", + "customers.accounts", "customers.source", "customers.destination" ] diff --git a/fixtures/reversals.json b/fixtures/reversals.json index 93f1ae7..1ff5569 100644 --- a/fixtures/reversals.json +++ b/fixtures/reversals.json @@ -17,6 +17,11 @@ "pattern": "/orders/{reversals.order}", "required": true }, + "reversals.account": { + "type": "string", + "format": "uri", + "pattern": "/settlements/{reversals.account}" + }, "reversals.events": { "type": "string", "format": "uri", @@ -27,6 +32,7 @@ "required": [ "reversals.credit", "reversals.order", + "reversals.account", "reversals.events" ] }, diff --git a/fixtures/settlements.json b/fixtures/settlements.json new file mode 100644 index 0000000..fb874ed --- /dev/null +++ b/fixtures/settlements.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "" + "links": { + "type": "object", + "properties": { + "settlements.destination": { + "type": "string", + "format": "uri", + "pattern": "/resources/{settlements.destination}", + "required": true + }, + "settlements.account": { + "type": "string", + "format": "uri", + "pattern": "/accounts/{settlements.account}", + "required": true + } + }, + "required": [ + "settlements.destination", + "settlements.account" + ] + }, + "meta": { + "$ref": "_models/meta.json" + }, + "settlements": { + "items": { + "$ref": "_models/settlement.json" + }, + "type": "array", + "minItems": 0, + "uniqueItems": true, + "required": true + } + }, + "required": [ + "links", + "settlements" + ] +} \ No newline at end of file From 306bee1f6195d16511a83ee050be4f3046a22d00 Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Mon, 20 Oct 2014 10:52:11 -0600 Subject: [PATCH 06/38] Create Settlements on POST to account settlements --- features/settlements.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/settlements.feature b/features/settlements.feature index fb0f57e..f2b271d 100644 --- a/features/settlements.feature +++ b/features/settlements.feature @@ -6,7 +6,7 @@ Feature: Settlements Scenario: Create a settlement Given I have an Account with sufficient funds And I have tokenized a bank account - When I POST to /settlements with the body: + When I POST to /accounts/:customer_deposit_account_id/settlements with the body: """ { "settlements": [{ From 6fe13fdbcb21cf23e05bc347b5dff2f6b51e3a71 Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Mon, 20 Oct 2014 10:53:00 -0600 Subject: [PATCH 07/38] Add credits and reversals links to Settlements --- fixtures/settlements.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fixtures/settlements.json b/fixtures/settlements.json index fb874ed..5ab1485 100644 --- a/fixtures/settlements.json +++ b/fixtures/settlements.json @@ -6,6 +6,16 @@ "links": { "type": "object", "properties": { + "settlements.credits": { + "type": "string", + "format": "uri", + "pattern": "/settlements/{settlements.id}/credits" + }, + "settlements.reversals": { + "type": "string", + "format": "uri", + "pattern": "/settlements/{settlements.id}/reversals" + }, "settlements.destination": { "type": "string", "format": "uri", @@ -20,6 +30,8 @@ } }, "required": [ + "settlements.credits", + "settlements.reversals", "settlements.destination", "settlements.account" ] From a9dd0a9ba7469318fbb54b04f9759545cccbadf2 Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Mon, 20 Oct 2014 10:53:40 -0600 Subject: [PATCH 08/38] Add reversals and refunds links to Accounts --- fixtures/accounts.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fixtures/accounts.json b/fixtures/accounts.json index 5e5a1a1..f7d0c13 100644 --- a/fixtures/accounts.json +++ b/fixtures/accounts.json @@ -20,6 +20,16 @@ "format": "uri", "pattern": "/accounts/{accounts.id}/debits" }, + "accounts.reversals": { + "type": "string", + "format": "uri", + "pattern": "/accounts/{accounts.id}/reversals" + }, + "accounts.refunds": { + "type": "string", + "format": "uri", + "pattern": "/accounts/{accounts.id}/refunds" + }, "accounts.settlements": { "type": "string", "format": "uri", @@ -31,6 +41,8 @@ "accounts.customer", "accounts.credits", "accounts.debits", + "accounts.reversals", + "accounts.refunds", "accounts.settlements" ] }, From 18d6292f42d9e25571dd85e9e86f02406b653fca Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Mon, 20 Oct 2014 11:10:35 -0600 Subject: [PATCH 09/38] Add type to Account. Remove deposit_account link from Customer. --- features/step_definitions/customers.rb | 9 +++++++-- fixtures/_models/account.json | 7 +++++++ fixtures/_models/customer.json | 9 --------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/features/step_definitions/customers.rb b/features/step_definitions/customers.rb index 0788130..6b23c01 100644 --- a/features/step_definitions/customers.rb +++ b/features/step_definitions/customers.rb @@ -11,8 +11,13 @@ ) @customer_id = @client['id'] @client.add_hydrate :customer_id, @customer_id - @client.add_hydrate :customer_deposit_account_id, @client['accounts']['deposit'] - + # get the deposit account + @client['accounts'].each do |acct| + if acct['type'] == 'deposit' + @client.add_hydrate :customer_deposit_account_id, acct['id'] + break + end + end @customer_url = @client['customers']['href'] # tokenize a card for them diff --git a/fixtures/_models/account.json b/fixtures/_models/account.json index c5878c8..e0e3a2a 100644 --- a/fixtures/_models/account.json +++ b/fixtures/_models/account.json @@ -29,6 +29,13 @@ "USD" ] }, + "type": { + "type": "string", + "enum": [ + "deposit", + "operating" + ] + }, "meta": { "type": "object" }, diff --git a/fixtures/_models/customer.json b/fixtures/_models/customer.json index 0eccbb8..f082c63 100644 --- a/fixtures/_models/customer.json +++ b/fixtures/_models/customer.json @@ -98,14 +98,6 @@ "links": { "type": "object", "properties": { - "accounts": [ - { - "deposit_account": { - "type": "string", - "pattern": "(AT)[a-zA-Z0-9]{16,32}" - } - } - ], "source": { "type": [ "null", @@ -122,7 +114,6 @@ } }, "required": [ - "accounts", "source", "destination" ], From 8045aba0015a32646cd98a69f638503b37ff8175 Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Tue, 21 Oct 2014 16:53:02 -0600 Subject: [PATCH 10/38] Remove type from Account --- fixtures/_models/account.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/fixtures/_models/account.json b/fixtures/_models/account.json index e0e3a2a..8557faa 100644 --- a/fixtures/_models/account.json +++ b/fixtures/_models/account.json @@ -29,12 +29,6 @@ "USD" ] }, - "type": { - "type": "string", - "enum": [ - "deposit", - "operating" - ] }, "meta": { "type": "object" From 0aeab757702762eb5fba93347e4bf8e8b7b2e4f3 Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Tue, 21 Oct 2014 16:53:13 -0600 Subject: [PATCH 11/38] Add can_debit and can_credit fields to Account --- fixtures/_models/account.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fixtures/_models/account.json b/fixtures/_models/account.json index 8557faa..fd20c2b 100644 --- a/fixtures/_models/account.json +++ b/fixtures/_models/account.json @@ -29,6 +29,13 @@ "USD" ] }, + "can_debit": { + "description": "Flag indicating whether this account can be debited (true) or not (false).", + "type": "boolean" + }, + "can_credit": { + "description": "Flag indicating whether this account instrument can be credited (true) or not (false).", + "type": "boolean" }, "meta": { "type": "object" @@ -54,6 +61,8 @@ "updated_at", "balance", "currency", + "can_credit", + "can_debit", "meta", "links" ] From 1e49b4d1fb21cfd47a71cb5203061e72b405ad5e Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Tue, 21 Oct 2014 17:17:18 -0600 Subject: [PATCH 12/38] POST settlements with no destination should 400 --- features/settlements.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/settlements.feature b/features/settlements.feature index f2b271d..45ed0b7 100644 --- a/features/settlements.feature +++ b/features/settlements.feature @@ -97,7 +97,7 @@ Feature: Settlements }] } """ - Then I should get a 409 status code + Then I should get a 400 status code And the response is valid according to the "errors" schema And the fields on this error match: """ From 642370e0ffb9b0742e169883922a8ac110249590 Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Tue, 21 Oct 2014 17:44:26 -0600 Subject: [PATCH 13/38] Use source instead --- fixtures/_models/settlement.json | 4 ++-- fixtures/credits.json | 6 ------ fixtures/reversals.json | 7 +------ fixtures/settlements.json | 6 +++--- 4 files changed, 6 insertions(+), 17 deletions(-) diff --git a/fixtures/_models/settlement.json b/fixtures/_models/settlement.json index 82e0f9b..e1ec6f1 100644 --- a/fixtures/_models/settlement.json +++ b/fixtures/_models/settlement.json @@ -62,14 +62,14 @@ "type": "string", "pattern": "BA[a-zA-Z0-9]{16,32}" }, - "account": { + "source": { "type": "string", "pattern": "AT[a-zA-Z0-9]{16,32}" } }, "required": [ "destination", - "account" + "source" ], } }, diff --git a/fixtures/credits.json b/fixtures/credits.json index 517b687..c2a3a73 100644 --- a/fixtures/credits.json +++ b/fixtures/credits.json @@ -25,11 +25,6 @@ "format": "uri", "pattern": "/resources/{credits.destination}" }, - "credits.account": { - "type": "string", - "format": "uri", - "pattern": "/accounts/{credits.account}" - }, "credits.events": { "type": "string", "format": "uri", @@ -41,7 +36,6 @@ "credits.customer", "credits.order", "credits.destination", - "credits.account", "credits.events" ] }, diff --git a/fixtures/reversals.json b/fixtures/reversals.json index 1ff5569..519c0d2 100644 --- a/fixtures/reversals.json +++ b/fixtures/reversals.json @@ -17,11 +17,6 @@ "pattern": "/orders/{reversals.order}", "required": true }, - "reversals.account": { - "type": "string", - "format": "uri", - "pattern": "/settlements/{reversals.account}" - }, "reversals.events": { "type": "string", "format": "uri", @@ -32,7 +27,7 @@ "required": [ "reversals.credit", "reversals.order", - "reversals.account", + "reversals.source", "reversals.events" ] }, diff --git a/fixtures/settlements.json b/fixtures/settlements.json index 5ab1485..5d66cc3 100644 --- a/fixtures/settlements.json +++ b/fixtures/settlements.json @@ -22,10 +22,10 @@ "pattern": "/resources/{settlements.destination}", "required": true }, - "settlements.account": { + "settlements.source": { "type": "string", "format": "uri", - "pattern": "/accounts/{settlements.account}", + "pattern": "/accounts/{settlements.source}", "required": true } }, @@ -33,7 +33,7 @@ "settlements.credits", "settlements.reversals", "settlements.destination", - "settlements.account" + "settlements.source" ] }, "meta": { From d3e31f8812b7a00a216e60ec191994988e5ffd3b Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Wed, 12 Nov 2014 18:51:37 -0700 Subject: [PATCH 14/38] More settlement scenarios. Cleanup. --- features/accounts.feature | 2 +- features/credits.feature | 10 ++-- features/orders.feature | 6 +- features/reversals.feature | 68 ++++++++++++++++++++++ features/settlements.feature | 20 ++++++- features/step_definitions/account.rb | 14 +++-- features/step_definitions/bank_accounts.rb | 14 ++++- features/step_definitions/customers.rb | 11 +++- features/step_definitions/orders.rb | 19 ++++-- features/step_definitions/settlements.rb | 4 +- fixtures/_models/bank_account.json | 8 --- fixtures/_models/settlement.json | 4 +- fixtures/settlements.json | 1 - 13 files changed, 140 insertions(+), 41 deletions(-) diff --git a/features/accounts.feature b/features/accounts.feature index bf38b58..4ae5817 100644 --- a/features/accounts.feature +++ b/features/accounts.feature @@ -23,7 +23,7 @@ Feature: Accounts Scenario: Credit a customer deposit account Given I have an order with a debit - When I POST to /accounts/:customer_deposit_account_id/credits + When I POST to /accounts/:customer_sweep_account_id/credits """ { "credits": [{ diff --git a/features/credits.feature b/features/credits.feature index f4e4279..1a41968 100644 --- a/features/credits.feature +++ b/features/credits.feature @@ -126,9 +126,9 @@ Feature: Credits """ - Scenario: Bulk credit to a customer deposit account + Scenario: Bulk credit to a customer sweep account Given I have a merchant with 2 orders with debits - When I POST to /accounts/:customer_deposit_account_id/credits with the body: + When I POST to /accounts/:customer_sweep_account_id/credits with the body: """ { "credits": [{ @@ -141,7 +141,7 @@ Feature: Credits Then I should get a 201 Created status code And the response is valid according to the "credits" schema - When I make a GET request to /accounts/:customer_deposit_account_id + When I make a GET request to /accounts/:customer_sweep_account_id Then I should get a 200 OK status code And the fields on this error match: """ @@ -150,7 +150,7 @@ Feature: Credits } """ - When I POST to /accounts/:customer_deposit_account_id/credits with the body: + When I POST to /accounts/:customer_sweep_account_id/credits with the body: """ { "credits": [{ @@ -163,7 +163,7 @@ Feature: Credits Then I should get a 201 Created status code And the response is valid according to the "credits" schema - When I make a GET request to /accounts/:customer_deposit_account_id/credits + When I make a GET request to /accounts/:customer_sweep_account_id/credits Then I should get a 200 OK status code And the fields on this error match: """ diff --git a/features/orders.feature b/features/orders.feature index e6d315f..0fb3431 100644 --- a/features/orders.feature +++ b/features/orders.feature @@ -123,7 +123,7 @@ Feature: Orders Scenario: Checking escrow of order after creating a credit Given I have an order with a debit - And I have tokenized a bank account and associated with the merchant + And I have tokenized a bank account associated with the merchant And I POST to /bank_accounts/:bank_account_id/credits with the body: """ { @@ -146,7 +146,7 @@ Feature: Orders Scenario: Orders cannot be credited more than escrow balance Given I have created an order - And I have tokenized a bank account and associated with the merchant + And I have tokenized a bank account associated with the merchant And I have tokenized a customer card And I make a POST request to the link "cards.debits" with the body: """ @@ -252,7 +252,7 @@ Feature: Orders }] } """ - And I have tokenized a bank account and associated with the merchant + And I have tokenized a bank account associated with the merchant Then I make a POST request to the link "bank_accounts.credits" with the body: """ { diff --git a/features/reversals.feature b/features/reversals.feature index 0a806ab..6d3a0cb 100644 --- a/features/reversals.feature +++ b/features/reversals.feature @@ -159,3 +159,71 @@ Feature: Reversal """ { "status": "failed" } """ + + Scenario: Reverse an Account credit before settlement + Given I have an Account with sufficient funds + When I POST to /credits/:credit_2_id/reversals with the body: + """ + { + "reversals": [{ + "amount": 1000 + }] + } + """ + Then I should get a 201 Created status code + And the response is valid according to the "reversals" schema + And the fields on this reversal match: + """ + { "status": "succeeded" } + """ + + Scenario: Reverse an Account credit after settlement + Given I have an Account with sufficient funds + When I make a POST request to the link "accounts.settlements" with the body: + """ + { + "settlements": [{ + "description": "Batch A", + "destination": /bank_accounts/:bank_account_id + }] + } + """ + Then I should get a 201 Created status code + And the response is valid according to the "reversals" schema + And the fields on this reversal match: + """ + { + "amount": 3000, + "status": "pending" + } + """ + + When I POST to /credits/:credit_id_2/reversals + Then I should get a 201 Created status code + And the response is valid according to the "reversals" schema + And the fields on this reversal match: + """ + { + "amount": 1000, + "status": "pending" + } + """ + + When I make a POST request to the link "accounts.settlements" + Then I should get a 201 Created status code + And the response is valid according to the "settlements" schema + + When I GET to /reversals/:reversal_id + Then I should get a 200 OK status code + And the response is valid according to the "reversals" schema + And the fields on this credit match: + """ + { "status": "succeeded" } + """ + + When I make a GET request to the link "reversals.order" + Then I should get a 200 OK status code + And the fields on this order match: + """ + { "amount_escrowed": 1000 } + """ \ No newline at end of file diff --git a/features/settlements.feature b/features/settlements.feature index 45ed0b7..3b9461f 100644 --- a/features/settlements.feature +++ b/features/settlements.feature @@ -1,4 +1,3 @@ -@focus Feature: Settlements Settlement is the action of moving money out of an Account to a bank account. @@ -6,7 +5,7 @@ Feature: Settlements Scenario: Create a settlement Given I have an Account with sufficient funds And I have tokenized a bank account - When I POST to /accounts/:customer_deposit_account_id/settlements with the body: + When I POST to /accounts/:customer_sweep_account_id/settlements with the body: """ { "settlements": [{ @@ -106,3 +105,20 @@ Feature: Settlements } """ + Scenario: Settlement fails + Given I have an Account with sufficient funds + And I have tokenized a failing bank account associated with the merchant + When I POST to /settlements with the body: + """ + { + "settlements": [{ + "description": "Will this settlement work? Certainly not!" + }] + } + """ + Then I should get a 201 Created status code + And the response is valid according to the "settlements" schema + And the fields on this error match: + """ + { "status": "failed" } + """ diff --git a/features/step_definitions/account.rb b/features/step_definitions/account.rb index 91c7468..b7d1361 100644 --- a/features/step_definitions/account.rb +++ b/features/step_definitions/account.rb @@ -1,8 +1,10 @@ Given(/^I have an Account with sufficient funds$/) do - step 'I have an order with a debit' - @client.post("/accounts/#{@customer_deposit_account_id}/credits", { - amount: 10000, - order: @order_id - }) - @client.add_hydrate :credit_id, @client['id'] + step 'I have a merchant with 3 orders with debits' + 3.times do |i| + @client.post("/accounts/#{@customer_sweep_account_id}/credits", { + amount: 10000, + order: "/orders/" + instance_variable_get("@order_id_#{i}") + }) + @client.add_hydrate "credit_id_#{i}".to_sym, @client['id'] + end end \ No newline at end of file diff --git a/features/step_definitions/bank_accounts.rb b/features/step_definitions/bank_accounts.rb index 2d80251..111b324 100644 --- a/features/step_definitions/bank_accounts.rb +++ b/features/step_definitions/bank_accounts.rb @@ -1,6 +1,6 @@ Given(/^I have tokenized a bank account$/) do @client.post('/bank_accounts', { - name: "Hhenry Ford", + name: "Henry Ford", routing_number: "321174851", account_number: "9900000001", account_type: "checking", @@ -10,12 +10,22 @@ @client.add_hydrate(:bank_accounts_id, @bank_account_id) end +Given(/^I have tokenized a failing bank account$/) do + @client.post('/bank_accounts', { + name: "Henry Ford", + routing_number: "021000021", + account_number: "9900000004", + account_type: "checking", + }) + @bank_account_id = @client['bank_accounts']['id'] + @client.add_hydrate(:bank_account_id, @bank_account_id) + @client.add_hydrate(:bank_accounts_id, @bank_account_id) +end Given(/^I have tokenized more than one bank account$/) do 2.times { step 'I have tokenized a bank account' } end - Given(/^I have a verified bank account$/) do step 'I have tokenized a bank account' @client.post("/bank_accounts/#{@bank_account_id}/verifications", {}) diff --git a/features/step_definitions/customers.rb b/features/step_definitions/customers.rb index 6b23c01..b9f2f30 100644 --- a/features/step_definitions/customers.rb +++ b/features/step_definitions/customers.rb @@ -11,10 +11,10 @@ ) @customer_id = @client['id'] @client.add_hydrate :customer_id, @customer_id - # get the deposit account + # get the sweep account @client['accounts'].each do |acct| - if acct['type'] == 'deposit' - @client.add_hydrate :customer_deposit_account_id, acct['id'] + if acct['type'] == 'sweep' + @client.add_hydrate :customer_sweep_account_id, acct['id'] break end end @@ -58,6 +58,11 @@ @client.get(@customer_url) end +Given(/^I have a customer with a bank account that results in failing credits/) do + step 'I have created a customer' + step 'I have tokenized a failing bank account and associated with the merchant' +end + Given(/^I have created a customer without a card and bank account$/) do @client.post('/customers', {}) @customer_id = @client['id'] diff --git a/features/step_definitions/orders.rb b/features/step_definitions/orders.rb index 84e584e..be47c39 100644 --- a/features/step_definitions/orders.rb +++ b/features/step_definitions/orders.rb @@ -21,8 +21,7 @@ @client.add_hydrate :debit_id, @client['id'] end - -When(/^I have tokenized a bank account and associated with the merchant$/) do +Given(/^I have tokenized a bank account associated with the merchant$/) do step 'I have tokenized a bank account' @client.put("/bank_accounts/#{@bank_account_id}", { links: { @@ -31,12 +30,20 @@ }) end +Given(/^I have tokenized a failing bank account associated with the merchant$/) do + step 'I have tokenized a failing bank account' + @client.put("/bank_accounts/#{@bank_account_id}", { + links: { + customer: @merchant_id + } + }) +end Given(/^I have a merchant with an order with the body:$/) do |body| step 'I have created a customer' @merchant_id = @customer_id @client.add_hydrate :merchant_id, @merchant_id - step 'I have tokenized a bank account and associated with the merchant' + step 'I have tokenized a bank account associated with the merchant' @client.post("/customers/#{@merchant_id}/orders", @client.hydrater(body)) @client.add_hydrate :order_id, @client['id'] end @@ -63,16 +70,16 @@ @client.post('/customers', {}) @merchant_id = @client['id'] @client.add_hydrate :merchant_id, @merchant_id - step 'I have tokenized a bank account and associated with the merchant' + step 'I have tokenized a bank account associated with the merchant' num.to_i.times do |i| @client.post("/customers/#{@merchant_id}/orders", {}) order_id = @client['id'] @client.add_hydrate :order_id, order_id @client.post("/cards/#{@card_id}/debits", { - amount: 12345, + amount: 10000, order: order_id }) - @client.add_hydrate :debit_id, @merchant_id + @client.add_hydrate :debit_id, @client['id'] instance_variable_set("@order_id_#{i + 1}", order_id) end end \ No newline at end of file diff --git a/features/step_definitions/settlements.rb b/features/step_definitions/settlements.rb index a82b2dc..c871a1b 100644 --- a/features/step_definitions/settlements.rb +++ b/features/step_definitions/settlements.rb @@ -1,7 +1,7 @@ Given(/^I have a bank account with a settlement$/) do step 'I have an order with a debit' step 'I have created a customer' - @client.post("/accounts/#{@customer_deposit_account_id}/credits", { + @client.post("/accounts/#{@customer_sweep_account_id}/credits", { amount: 1234, order: :order_id }) @@ -9,6 +9,6 @@ @client.add_hydrate :settlement_id, @settlement_id end -Given(/^I have (\d) settlements$/) do +Given(/^I have (\d) settlements$/) do |num| num.to_i.times { step 'I have a bank account with a settlement' } end diff --git a/fixtures/_models/bank_account.json b/fixtures/_models/bank_account.json index 350d65b..5e0e8a7 100644 --- a/fixtures/_models/bank_account.json +++ b/fixtures/_models/bank_account.json @@ -84,14 +84,6 @@ "string" ], "pattern": "BZ[a-zA-Z0-9]{16,32}" - }, - "sweep_account": { - "description": "A funding instrument representing a sweep account used for bulk credits", - "type": [ - "null", - "string" - ], - "pattern": "(AT)[a-zA-Z0-9]{16,32}" } }, "required": [ diff --git a/fixtures/_models/settlement.json b/fixtures/_models/settlement.json index e1ec6f1..5f749e9 100644 --- a/fixtures/_models/settlement.json +++ b/fixtures/_models/settlement.json @@ -4,7 +4,7 @@ "properties": { "id": { "type": "string", - "pattern": "(ST)[a-zA-Z0-9]{16,32}" + "pattern": "ST[a-zA-Z0-9]{16,32}" }, "href": { "type": "string", @@ -70,7 +70,7 @@ "required": [ "destination", "source" - ], + ] } }, "additionalProperties": false, diff --git a/fixtures/settlements.json b/fixtures/settlements.json index 5d66cc3..f84f8b9 100644 --- a/fixtures/settlements.json +++ b/fixtures/settlements.json @@ -2,7 +2,6 @@ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { - "" "links": { "type": "object", "properties": { From e4d8cbf4aa409a23f35029f7f3fe54e9246c8973 Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Thu, 13 Nov 2014 14:43:36 -0700 Subject: [PATCH 15/38] Fix settlement reversals scenarios --- features/reversals.feature | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/features/reversals.feature b/features/reversals.feature index 6d3a0cb..cb87965 100644 --- a/features/reversals.feature +++ b/features/reversals.feature @@ -189,12 +189,12 @@ Feature: Reversal } """ Then I should get a 201 Created status code - And the response is valid according to the "reversals" schema - And the fields on this reversal match: + And the response is valid according to the "settlements" schema + And the fields on this settlements match: """ { - "amount": 3000, - "status": "pending" + "amount": 30000, + "status": "succeeded" } """ @@ -204,7 +204,7 @@ Feature: Reversal And the fields on this reversal match: """ { - "amount": 1000, + "amount": 10000, "status": "pending" } """ @@ -226,4 +226,4 @@ Feature: Reversal And the fields on this order match: """ { "amount_escrowed": 1000 } - """ \ No newline at end of file + """ From 745d0432a4abf5a380ee6ebb9363f7e0fe579b2b Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Thu, 13 Nov 2014 14:48:19 -0700 Subject: [PATCH 16/38] Add settlement scenario account insufficient funds --- features/settlements.feature | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/features/settlements.feature b/features/settlements.feature index 3b9461f..e763139 100644 --- a/features/settlements.feature +++ b/features/settlements.feature @@ -105,6 +105,25 @@ Feature: Settlements } """ + Scenario: Creating a settlement for an Account with insufficient funds fails + Given I have created a customer + When I POST to /accounts/:customer_sweep_account_id/settlements with the body: + """ + { + "settlements": [{ + "destination": "/bank_accounts/:bank_account_id" + }] + } + """ + Then I should get a 409 status code + And the response is valid according to the "errors" schema + And the fields on this error match: + """ + { + "category_code": "account-nothing-to-settle" + } + """ + Scenario: Settlement fails Given I have an Account with sufficient funds And I have tokenized a failing bank account associated with the merchant From 2e3b457a19014703c0d6c9288031562493b54b38 Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Thu, 13 Nov 2014 14:50:56 -0700 Subject: [PATCH 17/38] More descriptive Accounts description --- features/accounts.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/accounts.feature b/features/accounts.feature index 4ae5817..b647690 100644 --- a/features/accounts.feature +++ b/features/accounts.feature @@ -1,5 +1,5 @@ Feature: Accounts - Accounts are a way to have a store of some kind of value. + Accounts are funding instruments which are able to store a balance internally with the Balanced system. Scenario: List accounts Given I have created a customer From f2c7675fc1669e92e9b3f44cc668a128ce73c75f Mon Sep 17 00:00:00 2001 From: richie serna Date: Fri, 5 Dec 2014 15:01:37 -0800 Subject: [PATCH 18/38] Fix bulk credit feature --- features/accounts.feature | 2 +- features/credits.feature | 14 +++++++------- features/settlements.feature | 4 ++-- features/step_definitions/account.rb | 5 +++-- features/step_definitions/customers.rb | 12 ++++++------ features/step_definitions/http_steps.rb | 1 - features/step_definitions/settlements.rb | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/features/accounts.feature b/features/accounts.feature index b647690..1e26246 100644 --- a/features/accounts.feature +++ b/features/accounts.feature @@ -23,7 +23,7 @@ Feature: Accounts Scenario: Credit a customer deposit account Given I have an order with a debit - When I POST to /accounts/:customer_sweep_account_id/credits + When I POST to /accounts/:customer_payable_account_id/credits """ { "credits": [{ diff --git a/features/credits.feature b/features/credits.feature index 1a41968..ae9decd 100644 --- a/features/credits.feature +++ b/features/credits.feature @@ -126,9 +126,9 @@ Feature: Credits """ - Scenario: Bulk credit to a customer sweep account + Scenario: Bulk credit to a customer payable account Given I have a merchant with 2 orders with debits - When I POST to /accounts/:customer_sweep_account_id/credits with the body: + When I POST to /accounts/:customer_payable_account_id/credits with the body: """ { "credits": [{ @@ -141,16 +141,16 @@ Feature: Credits Then I should get a 201 Created status code And the response is valid according to the "credits" schema - When I make a GET request to /accounts/:customer_sweep_account_id + When I make a GET request to /accounts/:customer_payable_account_id Then I should get a 200 OK status code - And the fields on this error match: + And the fields on this account match: """ { "balance": 1000 } """ - When I POST to /accounts/:customer_sweep_account_id/credits with the body: + When I POST to /accounts/:customer_payable_account_id/credits with the body: """ { "credits": [{ @@ -163,9 +163,9 @@ Feature: Credits Then I should get a 201 Created status code And the response is valid according to the "credits" schema - When I make a GET request to /accounts/:customer_sweep_account_id/credits + When I make a GET request to /accounts/:customer_payable_account_id Then I should get a 200 OK status code - And the fields on this error match: + And the fields on this account match: """ { "balance": 2000 diff --git a/features/settlements.feature b/features/settlements.feature index e763139..3436688 100644 --- a/features/settlements.feature +++ b/features/settlements.feature @@ -5,7 +5,7 @@ Feature: Settlements Scenario: Create a settlement Given I have an Account with sufficient funds And I have tokenized a bank account - When I POST to /accounts/:customer_sweep_account_id/settlements with the body: + When I POST to /accounts/:customer_payable_account_id/settlements with the body: """ { "settlements": [{ @@ -107,7 +107,7 @@ Feature: Settlements Scenario: Creating a settlement for an Account with insufficient funds fails Given I have created a customer - When I POST to /accounts/:customer_sweep_account_id/settlements with the body: + When I POST to /accounts/:customer_payable_account_id/settlements with the body: """ { "settlements": [{ diff --git a/features/step_definitions/account.rb b/features/step_definitions/account.rb index b7d1361..9fa9f42 100644 --- a/features/step_definitions/account.rb +++ b/features/step_definitions/account.rb @@ -1,10 +1,11 @@ Given(/^I have an Account with sufficient funds$/) do step 'I have a merchant with 3 orders with debits' 3.times do |i| - @client.post("/accounts/#{@customer_sweep_account_id}/credits", { + @client.post("/accounts/#{@customer_payable_account_id}/credits", { amount: 10000, order: "/orders/" + instance_variable_get("@order_id_#{i}") }) @client.add_hydrate "credit_id_#{i}".to_sym, @client['id'] end -end \ No newline at end of file +end + diff --git a/features/step_definitions/customers.rb b/features/step_definitions/customers.rb index b9f2f30..bd01cb6 100644 --- a/features/step_definitions/customers.rb +++ b/features/step_definitions/customers.rb @@ -10,15 +10,16 @@ } ) @customer_id = @client['id'] + @customer_url = @client['href'] + @accounts = @client.get("#{@customer_url}/accounts")['accounts'] @client.add_hydrate :customer_id, @customer_id - # get the sweep account - @client['accounts'].each do |acct| - if acct['type'] == 'sweep' - @client.add_hydrate :customer_sweep_account_id, acct['id'] + # get the payable account + @accounts.each do |acct| + if acct['type'] == 'payable' + @client.add_hydrate :customer_payable_account_id, acct['id'] break end end - @customer_url = @client['customers']['href'] # tokenize a card for them @client.post('/cards', @@ -51,7 +52,6 @@ value: @card_id }] ) - ## TODO: fix hax # Right now, we rely on last_body in places becuase the client is mutable # this is bad and we should stop it. diff --git a/features/step_definitions/http_steps.rb b/features/step_definitions/http_steps.rb index d111711..b28b177 100644 --- a/features/step_definitions/http_steps.rb +++ b/features/step_definitions/http_steps.rb @@ -62,7 +62,6 @@ def env body = @client.hydrater(body) href = @client.get_link(keys) #$logger.debug("Requesting hydrated: #{@client.hydrater(@client.last_body["links"][keys])}") - #require 'debugger'; debugger body = @client.send(verb.downcase, @client.get_link(keys), JSON.parse(body), env) @credit_id = @client['credits']['id'] rescue nil @cards_id = @client['cards']['id'] rescue nil diff --git a/features/step_definitions/settlements.rb b/features/step_definitions/settlements.rb index c871a1b..b1f1897 100644 --- a/features/step_definitions/settlements.rb +++ b/features/step_definitions/settlements.rb @@ -1,7 +1,7 @@ Given(/^I have a bank account with a settlement$/) do step 'I have an order with a debit' step 'I have created a customer' - @client.post("/accounts/#{@customer_sweep_account_id}/credits", { + @client.post("/accounts/#{@customer_payable_account_id}/credits", { amount: 1234, order: :order_id }) From 8ef847030ec07f17f740c75fe44303b715cb1859 Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Fri, 5 Dec 2014 17:16:07 -0700 Subject: [PATCH 19/38] Fix some errors --- features/reversals.feature | 7 ++++--- features/step_definitions/account.rb | 3 ++- features/step_definitions/customers.rb | 1 + fixtures/reversals.json | 1 - 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/features/reversals.feature b/features/reversals.feature index cb87965..c07a918 100644 --- a/features/reversals.feature +++ b/features/reversals.feature @@ -179,12 +179,13 @@ Feature: Reversal Scenario: Reverse an Account credit after settlement Given I have an Account with sufficient funds - When I make a POST request to the link "accounts.settlements" with the body: + When I POST to /accounts/:customer_payable_account_id/settlements with the body: + """ { "settlements": [{ "description": "Batch A", - "destination": /bank_accounts/:bank_account_id + "funding_instrument": /bank_accounts/:bank_account_id }] } """ @@ -209,7 +210,7 @@ Feature: Reversal } """ - When I make a POST request to the link "accounts.settlements" + When POST to /accounts/:customer_payable_account_id/settlements Then I should get a 201 Created status code And the response is valid according to the "settlements" schema diff --git a/features/step_definitions/account.rb b/features/step_definitions/account.rb index 9fa9f42..bcaf0e3 100644 --- a/features/step_definitions/account.rb +++ b/features/step_definitions/account.rb @@ -1,9 +1,10 @@ Given(/^I have an Account with sufficient funds$/) do step 'I have a merchant with 3 orders with debits' 3.times do |i| + order_href = "/orders/" + instance_variable_get("@order_id_#{i + 1}") @client.post("/accounts/#{@customer_payable_account_id}/credits", { amount: 10000, - order: "/orders/" + instance_variable_get("@order_id_#{i}") + order: order_href }) @client.add_hydrate "credit_id_#{i}".to_sym, @client['id'] end diff --git a/features/step_definitions/customers.rb b/features/step_definitions/customers.rb index bd01cb6..05358c4 100644 --- a/features/step_definitions/customers.rb +++ b/features/step_definitions/customers.rb @@ -17,6 +17,7 @@ @accounts.each do |acct| if acct['type'] == 'payable' @client.add_hydrate :customer_payable_account_id, acct['id'] + @customer_payable_account_id = acct['id'] break end end diff --git a/fixtures/reversals.json b/fixtures/reversals.json index 519c0d2..93f1ae7 100644 --- a/fixtures/reversals.json +++ b/fixtures/reversals.json @@ -27,7 +27,6 @@ "required": [ "reversals.credit", "reversals.order", - "reversals.source", "reversals.events" ] }, From d1e4036b540c64ea286fbdb07f1b334b876a39f6 Mon Sep 17 00:00:00 2001 From: richie serna Date: Fri, 5 Dec 2014 18:07:43 -0800 Subject: [PATCH 20/38] Edit create customer step --- features/step_definitions/customers.rb | 1 + features/step_definitions/orders.rb | 5 ++--- features/step_definitions/settlements.rb | 9 ++++++--- fixtures/reversals.json | 1 - fixtures/settlements.json | 8 +++++++- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/features/step_definitions/customers.rb b/features/step_definitions/customers.rb index bd01cb6..05358c4 100644 --- a/features/step_definitions/customers.rb +++ b/features/step_definitions/customers.rb @@ -17,6 +17,7 @@ @accounts.each do |acct| if acct['type'] == 'payable' @client.add_hydrate :customer_payable_account_id, acct['id'] + @customer_payable_account_id = acct['id'] break end end diff --git a/features/step_definitions/orders.rb b/features/step_definitions/orders.rb index be47c39..04b17bb 100644 --- a/features/step_definitions/orders.rb +++ b/features/step_definitions/orders.rb @@ -8,10 +8,9 @@ Given(/^I have an order with a debit$/) do step 'I have created a customer' - @client.post('/customers', {}) - @merchant_id = @client['id'] + @merchant_id = @customer_id @client.add_hydrate :merchant_id, @client['id'] - @client.post("/customers/#{@client['id']}/orders", {}) + @client.post("/customers/#{@merchant_id}/orders", {}) @order_id = @client['id'] @client.add_hydrate :order_id, @order_id @client.post("/cards/#{@card_id}/debits", { diff --git a/features/step_definitions/settlements.rb b/features/step_definitions/settlements.rb index b1f1897..6cc6a12 100644 --- a/features/step_definitions/settlements.rb +++ b/features/step_definitions/settlements.rb @@ -1,9 +1,12 @@ Given(/^I have a bank account with a settlement$/) do step 'I have an order with a debit' - step 'I have created a customer' + step 'I have tokenized a bank account associated with the merchant' @client.post("/accounts/#{@customer_payable_account_id}/credits", { - amount: 1234, - order: :order_id + amount: 12345, + order: @order_id + }) + @client.post("/accounts/#{@customer_payable_account_id}/settlements", { + funding_instrument: :"/bank_accounts/#{@bank_account_id}" }) @settlement_id = @client['settlements']['id'] @client.add_hydrate :settlement_id, @settlement_id diff --git a/fixtures/reversals.json b/fixtures/reversals.json index 519c0d2..93f1ae7 100644 --- a/fixtures/reversals.json +++ b/fixtures/reversals.json @@ -27,7 +27,6 @@ "required": [ "reversals.credit", "reversals.order", - "reversals.source", "reversals.events" ] }, diff --git a/fixtures/settlements.json b/fixtures/settlements.json index f84f8b9..8096cec 100644 --- a/fixtures/settlements.json +++ b/fixtures/settlements.json @@ -24,7 +24,13 @@ "settlements.source": { "type": "string", "format": "uri", - "pattern": "/accounts/{settlements.source}", + "pattern": "/resources/{settlements.source}", + "required": true + }, + "settlements.events": { + "type": "string", + "format": "uri", + "pattern": "/events/{settlements.id}/events", "required": true } }, From 1365a5b01b76a3581467c69ef7df4833145892fe Mon Sep 17 00:00:00 2001 From: richie serna Date: Fri, 5 Dec 2014 19:47:06 -0800 Subject: [PATCH 21/38] Fix syntax error in reversals, clean up settlements steps --- features/reversals.feature | 4 +--- features/settlements.feature | 15 +++++++++------ features/step_definitions/account.rb | 5 +++-- features/step_definitions/orders.rb | 3 +-- fixtures/_models/error.json | 3 ++- fixtures/settlements.json | 2 +- 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/features/reversals.feature b/features/reversals.feature index c07a918..f498f24 100644 --- a/features/reversals.feature +++ b/features/reversals.feature @@ -180,12 +180,10 @@ Feature: Reversal Scenario: Reverse an Account credit after settlement Given I have an Account with sufficient funds When I POST to /accounts/:customer_payable_account_id/settlements with the body: - """ { "settlements": [{ - "description": "Batch A", - "funding_instrument": /bank_accounts/:bank_account_id + "funding_instrument": "/bank_accounts/:bank_account_id" }] } """ diff --git a/features/settlements.feature b/features/settlements.feature index 3436688..5ffc4b1 100644 --- a/features/settlements.feature +++ b/features/settlements.feature @@ -9,7 +9,7 @@ Feature: Settlements """ { "settlements": [{ - "destination": "/bank_accounts/:bank_account_id", + "funding_instrument": "/bank_accounts/:bank_account_id", "appears_on_statement_as": "Settlement Oct", "description": "Settlement for payouts from October" }] @@ -84,11 +84,13 @@ Feature: Settlements "meta": { "reference_number": "546512" } + } """ Scenario: Creating a settlement without a funding destination leads to failure - When I POST to /settlements with the body: + Given I have a customer with a tokenized bank account + When I POST to /accounts/:customer_payable_account_id/settlements with the body: """ { "settlements": [{ @@ -106,12 +108,12 @@ Feature: Settlements """ Scenario: Creating a settlement for an Account with insufficient funds fails - Given I have created a customer + Given I have a customer with a tokenized bank account When I POST to /accounts/:customer_payable_account_id/settlements with the body: """ { "settlements": [{ - "destination": "/bank_accounts/:bank_account_id" + "funding_instrument": "/bank_accounts/:bank_account_id" }] } """ @@ -127,11 +129,12 @@ Feature: Settlements Scenario: Settlement fails Given I have an Account with sufficient funds And I have tokenized a failing bank account associated with the merchant - When I POST to /settlements with the body: + When I POST to /accounts/:customer_payable_account_id/settlements with the body: """ { "settlements": [{ - "description": "Will this settlement work? Certainly not!" + "funding_instrument": "/bank_accounts/:bank_account_id", + "description": "Will this settlement work? Certainly not!" }] } """ diff --git a/features/step_definitions/account.rb b/features/step_definitions/account.rb index bcaf0e3..723ee53 100644 --- a/features/step_definitions/account.rb +++ b/features/step_definitions/account.rb @@ -2,11 +2,12 @@ step 'I have a merchant with 3 orders with debits' 3.times do |i| order_href = "/orders/" + instance_variable_get("@order_id_#{i + 1}") - @client.post("/accounts/#{@customer_payable_account_id}/credits", { + response = @client.post("/accounts/#{@customer_payable_account_id}/credits", { amount: 10000, order: order_href }) - @client.add_hydrate "credit_id_#{i}".to_sym, @client['id'] + @client.add_hydrate "credit_id_#{i}".to_sym, response['credits'][0]['id'] + end end diff --git a/features/step_definitions/orders.rb b/features/step_definitions/orders.rb index 04b17bb..b0c5e09 100644 --- a/features/step_definitions/orders.rb +++ b/features/step_definitions/orders.rb @@ -66,8 +66,7 @@ Given(/^I have a merchant with (\d) orders with debits$/) do |num| step 'I have created a customer' - @client.post('/customers', {}) - @merchant_id = @client['id'] + @merchant_id = @customer_id @client.add_hydrate :merchant_id, @merchant_id step 'I have tokenized a bank account associated with the merchant' num.to_i.times do |i| diff --git a/fixtures/_models/error.json b/fixtures/_models/error.json index 4e97936..2916319 100644 --- a/fixtures/_models/error.json +++ b/fixtures/_models/error.json @@ -77,7 +77,8 @@ "order-kyc", "method-not-allowed", "duplicate-webhook-url", - "amount-exceeds-limit" + "amount-exceeds-limit", + "account-nothing-to-settle" ] }, "description": { diff --git a/fixtures/settlements.json b/fixtures/settlements.json index 8096cec..e53b55a 100644 --- a/fixtures/settlements.json +++ b/fixtures/settlements.json @@ -30,7 +30,7 @@ "settlements.events": { "type": "string", "format": "uri", - "pattern": "/events/{settlements.id}/events", + "pattern": "/settlements/{settlements.id}/events", "required": true } }, From 9a36b43954d4adcc9382fa7e964db26c70fe68b3 Mon Sep 17 00:00:00 2001 From: richie serna Date: Mon, 8 Dec 2014 11:56:26 -0800 Subject: [PATCH 22/38] Change categroy code for missing funding instrument to request --- features/credits.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/credits.feature b/features/credits.feature index ae9decd..1d70aff 100644 --- a/features/credits.feature +++ b/features/credits.feature @@ -121,7 +121,7 @@ Feature: Credits And the fields on this error match: """ { - "category_code": "no-funding-destination" + "category_code": "request" } """ From 676ffecf927bd2d6c060c7d7bb40c98de5bad97c Mon Sep 17 00:00:00 2001 From: richie serna Date: Mon, 8 Dec 2014 11:56:58 -0800 Subject: [PATCH 23/38] Fix variable for credit_id_2 --- features/reversals.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/reversals.feature b/features/reversals.feature index f498f24..d680cb5 100644 --- a/features/reversals.feature +++ b/features/reversals.feature @@ -162,7 +162,7 @@ Feature: Reversal Scenario: Reverse an Account credit before settlement Given I have an Account with sufficient funds - When I POST to /credits/:credit_2_id/reversals with the body: + When I POST to /credits/:credit_id_2/reversals with the body: """ { "reversals": [{ From 8e6280eec813a3f609d046b5cb1c2879408a2366 Mon Sep 17 00:00:00 2001 From: richie serna Date: Mon, 8 Dec 2014 11:59:05 -0800 Subject: [PATCH 24/38] change back category code for credits, edit settlements instead --- features/credits.feature | 2 +- features/settlements.feature | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/credits.feature b/features/credits.feature index 1d70aff..ae9decd 100644 --- a/features/credits.feature +++ b/features/credits.feature @@ -121,7 +121,7 @@ Feature: Credits And the fields on this error match: """ { - "category_code": "request" + "category_code": "no-funding-destination" } """ diff --git a/features/settlements.feature b/features/settlements.feature index 5ffc4b1..ae31e99 100644 --- a/features/settlements.feature +++ b/features/settlements.feature @@ -103,7 +103,7 @@ Feature: Settlements And the fields on this error match: """ { - "category_code": "no-funding-destination" + "category_code": "request" } """ From b617c04d3b2cbb609cd97e237ddd9a46cf590c8d Mon Sep 17 00:00:00 2001 From: richie serna Date: Mon, 8 Dec 2014 12:34:50 -0800 Subject: [PATCH 25/38] Fix account step, missing with body: --- features/accounts.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/accounts.feature b/features/accounts.feature index 1e26246..f552548 100644 --- a/features/accounts.feature +++ b/features/accounts.feature @@ -21,9 +21,9 @@ Feature: Accounts } """ - Scenario: Credit a customer deposit account + Scenario: Credit a customer payable account Given I have an order with a debit - When I POST to /accounts/:customer_payable_account_id/credits + When I POST to /accounts/:customer_payable_account_id/credits with the body: """ { "credits": [{ From 2b66e229949b0b3fd3c443e4a8713ef96a2623fb Mon Sep 17 00:00:00 2001 From: richie serna Date: Wed, 10 Dec 2014 14:38:51 -0800 Subject: [PATCH 26/38] remove extra bank account call on settlement feature --- features/settlements.feature | 1 - features/step_definitions/orders.rb | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/features/settlements.feature b/features/settlements.feature index ae31e99..5dcf692 100644 --- a/features/settlements.feature +++ b/features/settlements.feature @@ -4,7 +4,6 @@ Feature: Settlements Scenario: Create a settlement Given I have an Account with sufficient funds - And I have tokenized a bank account When I POST to /accounts/:customer_payable_account_id/settlements with the body: """ { diff --git a/features/step_definitions/orders.rb b/features/step_definitions/orders.rb index b0c5e09..77128f1 100644 --- a/features/step_definitions/orders.rb +++ b/features/step_definitions/orders.rb @@ -9,7 +9,7 @@ Given(/^I have an order with a debit$/) do step 'I have created a customer' @merchant_id = @customer_id - @client.add_hydrate :merchant_id, @client['id'] + @client.add_hydrate :merchant_id, @merchant_id @client.post("/customers/#{@merchant_id}/orders", {}) @order_id = @client['id'] @client.add_hydrate :order_id, @order_id From 9b0f4344e27895e906716d76a0d5c47373fd7866 Mon Sep 17 00:00:00 2001 From: richie serna Date: Thu, 11 Dec 2014 11:53:36 -0800 Subject: [PATCH 27/38] Fix gsub issue causing malformed order ids --- features/step_definitions/orders.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/step_definitions/orders.rb b/features/step_definitions/orders.rb index 77128f1..e1d62a7 100644 --- a/features/step_definitions/orders.rb +++ b/features/step_definitions/orders.rb @@ -72,7 +72,7 @@ num.to_i.times do |i| @client.post("/customers/#{@merchant_id}/orders", {}) order_id = @client['id'] - @client.add_hydrate :order_id, order_id + @client.add_hydrate ":order_id_#{i + 1}", order_id @client.post("/cards/#{@card_id}/debits", { amount: 10000, order: order_id From e988cc9b5ae65bfdbe32358a2950aaf368661db7 Mon Sep 17 00:00:00 2001 From: richie serna Date: Thu, 11 Dec 2014 12:19:39 -0800 Subject: [PATCH 28/38] Correct typo in accounts feature --- features/accounts.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/accounts.feature b/features/accounts.feature index f552548..d04757e 100644 --- a/features/accounts.feature +++ b/features/accounts.feature @@ -12,7 +12,7 @@ Feature: Accounts When I GET to /customers/:customer_id/accounts Then I should get a 200 OK status code And the response is valid according to the "accounts" schema - And the fields on these credits match: + And the fields on these accounts match: """ { "links": { From ff15533e9946589e97275cdb48f96ba968c07c25 Mon Sep 17 00:00:00 2001 From: richie serna Date: Thu, 11 Dec 2014 12:53:44 -0800 Subject: [PATCH 29/38] Edit settlemtent fixture to accept transaction_number, fix broken reversals and settlements features --- features/reversals.feature | 6 +++--- features/settlements.feature | 4 ++-- features/step_definitions/account.rb | 1 - fixtures/_models/settlement.json | 4 ++++ 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/features/reversals.feature b/features/reversals.feature index d680cb5..5f81381 100644 --- a/features/reversals.feature +++ b/features/reversals.feature @@ -189,11 +189,11 @@ Feature: Reversal """ Then I should get a 201 Created status code And the response is valid according to the "settlements" schema - And the fields on this settlements match: + And the fields on this settlement match: """ { "amount": 30000, - "status": "succeeded" + "status": "pending" } """ @@ -204,7 +204,7 @@ Feature: Reversal """ { "amount": 10000, - "status": "pending" + "status": "succeeded" } """ diff --git a/features/settlements.feature b/features/settlements.feature index 5dcf692..1887274 100644 --- a/features/settlements.feature +++ b/features/settlements.feature @@ -19,7 +19,7 @@ Feature: Settlements And the fields on this settlement match: """ { - "amount": "10000", + "amount": 30000, "appears_on_statement_as": "BAL*Settlement Oct", "description": "Settlement for payouts from October", "links": { @@ -139,7 +139,7 @@ Feature: Settlements """ Then I should get a 201 Created status code And the response is valid according to the "settlements" schema - And the fields on this error match: + And the fields on this settlement match: """ { "status": "failed" } """ diff --git a/features/step_definitions/account.rb b/features/step_definitions/account.rb index 723ee53..26414ea 100644 --- a/features/step_definitions/account.rb +++ b/features/step_definitions/account.rb @@ -7,7 +7,6 @@ order: order_href }) @client.add_hydrate "credit_id_#{i}".to_sym, response['credits'][0]['id'] - end end diff --git a/fixtures/_models/settlement.json b/fixtures/_models/settlement.json index 5f749e9..e330d68 100644 --- a/fixtures/_models/settlement.json +++ b/fixtures/_models/settlement.json @@ -55,6 +55,10 @@ "meta": { "$ref": "meta.json" }, + "transaction_number": { + "type": "string", + "pattern": "SC[0-9A-Z]{3}-[0-9A-Z]{3}-[0-9A-Z]{4}" + }, "links": { "type": "object", "properties": { From f59e0dc9e33532361d68ab9e9db73f8d42d3c8a9 Mon Sep 17 00:00:00 2001 From: richie serna Date: Fri, 12 Dec 2014 17:24:22 -0800 Subject: [PATCH 30/38] Add new tests for accoutns --- features/accounts.feature | 92 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/features/accounts.feature b/features/accounts.feature index d04757e..25cf831 100644 --- a/features/accounts.feature +++ b/features/accounts.feature @@ -33,4 +33,94 @@ Feature: Accounts } """ Then I should get a 201 Created status code - And the response is valid according to the "credits" schema \ No newline at end of file + And the response is valid according to the "credits" schema + + Scenario: Retrieving credits for an account + Given I have an Account with sufficient funds + When I GET to /accounts/:customer_payable_account_id/credits + Then I should get a 200 OK status code + And the response is valid according to the "credits" schema + And the fields on these credits match: + """ + { + "links": { + "destination": ":customer_payable_account_id" + } + } + """ + + # Currently there are no debitable accounts + Scenario: Retrieving debits for an account + Given I have an Account with sufficient funds + When I GET to /accounts/:customer_payable_account_id/debits + Then I should get a 200 OK status code + And the fields on these debits match: + """ + { + "meta": { + "total": 0 + } + } + """ + + # Currently there are no debitable accounts, thus no refunds + Scenario: Retrieving refunds for an account + Given I have an Account with a credit + Then I POST to /credits/:credit_id/reversals + When I POST to /debits/:debit_id/refunds + Then I should get a 201 Created status code + And the response is valid according to the "refunds" schema + + When I GET to /accounts/:customer_payable_account_id/refunds + Then I should get a 200 OK status code + And the fields on these refunds match: + """ + { + "meta": { + "total": 0 + } + } + """ + + Scenario: Retrieving reversals for an account + Given I have an Account with a credit + Then I POST to /credits/:credit_id/reversals + Then I should get a 201 Created status code + And the response is valid according to the "reversals" schema + When I GET to /accounts/:customer_payable_account_id/reversals + Then I should get a 200 OK status code + And the response is valid according to the "reversals" schema + And the fields on these reversals match: + """ + { + "links": { + "credit": ":credit_id_1" + } + } + """ + + Scenario: Retrieving settlements for an account + Given I have an Account with sufficient funds + When I POST to /accounts/:customer_payable_account_id/settlements with the body: + """ + { + "settlements": [{ + "funding_instrument": "/bank_accounts/:bank_account_id", + "appears_on_statement_as": "Settlement Oct", + "description": "Settlement for payouts from October" + }] + } + """ + Then I should get a 201 Created status code + And the response is valid according to the "settlements" schema + When I GET to /accounts/:customer_payable_account_id/settlements + Then I should get a 200 OK status code + And the response is valid according to the "settlements" schema + And the fields on these settlements match: + """ + { + "links": { + "source": ":customer_payable_account_id" + } + } + """ \ No newline at end of file From aa0cc6f38df7e9173d34e07056b0a465c3c8fa9e Mon Sep 17 00:00:00 2001 From: richie serna Date: Fri, 12 Dec 2014 17:26:55 -0800 Subject: [PATCH 31/38] Add tests and fixtures for testing links for accounts and settlements --- features/customers.feature | 14 ++++++ features/settlements.feature | 60 ++++++++++++++++++++++++ features/step_definitions/account.rb | 23 +++++++++ features/step_definitions/orders.rb | 2 +- features/step_definitions/settlements.rb | 11 +++++ 5 files changed, 109 insertions(+), 1 deletion(-) diff --git a/features/customers.feature b/features/customers.feature index a00fb9c..2aaa3a4 100644 --- a/features/customers.feature +++ b/features/customers.feature @@ -232,3 +232,17 @@ Feature: Customers "merchant_status": "underwritten" } """ + + Scenario: Retrieving accounts for a customer + Given I have a bank account with a settlement + When I GET to /customers/:customer_id/accounts + Then I should get a 200 OK status code + And the response is valid according to the "accounts" schema + And the fields on these accounts match: + """ + { + "links": { + "customer": ":customer_id" + } + } + """ \ No newline at end of file diff --git a/features/settlements.feature b/features/settlements.feature index 1887274..7ceed01 100644 --- a/features/settlements.feature +++ b/features/settlements.feature @@ -143,3 +143,63 @@ Feature: Settlements """ { "status": "failed" } """ + + Scenario: Retrieving credits for a settlement + Given I have a bank account with a settlement + When I GET to /settlements/:settlement_id/credits + Then I should get a 200 OK status code + And the response is valid according to the "credits" schema + And the fields on these credits match: + """ + { + "links": { + "destination": ":customer_payable_account_id" + } + } + """ + + Scenario: Retrieving reversals for a settlement + Given I have a bank account with a settlement + Then I POST to /credits/:credit_id/reversals + Then I should get a 201 Created status code + And the response is valid according to the "reversals" schema + Then I settle the account + When I GET to /settlements/:settlement_id/reversals + Then I should get a 200 OK status codek + And the response is valid according to the "reversals" schema + And the fields on these reversals match: + """ + "links": { + "credit": ":credit_id" + } + """ + +Scenario: Retrieving events for a settlement + Given I have a bank account with a settlement + When I GET to /settlements/:settlement_id/events + Then I should get a 200 OK status code + And the response is valid according to the "events" schema + And the fields on these events match: + """ + { "href": ":settlement_id" } + """ + + Scenario: Retrieving source for a settlement + Given I have a bank account with a settlement + When I GET to /resources/:customer_payable_account_id + Then I should get a 200 OK status code + And the response is valid according to the "accounts" schema + And the fields on this account match: + """ + {"id": ":customer_payable_account_id"} + """ + + Scenario: Retrieving destination for a settlement + Given I have a bank account with a settlement + When I GET to /resources/:bank_account_id + Then I should get a 200 OK status code + And the response is valid according to the "bank_accounts" schema + And the fields on this bank_account match: + """ + {"id": ":bank_account_id"} + """ \ No newline at end of file diff --git a/features/step_definitions/account.rb b/features/step_definitions/account.rb index 26414ea..43cc2dd 100644 --- a/features/step_definitions/account.rb +++ b/features/step_definitions/account.rb @@ -10,3 +10,26 @@ end end + +Given(/^I have an Account with a credit$/) do + step 'I have created a customer' + @merchant_id = @customer_id + @client.add_hydrate :merchant_id, @merchant_id + step 'I have tokenized a bank account associated with the merchant' + @client.post("/customers/#{@merchant_id}/orders", {}) + order_id = @client['id'] + @client.add_hydrate :order_id, order_id + @client.post("/cards/#{@card_id}/debits", { + amount: 10000, + order: order_id + }) + @client.add_hydrate :debit_id, @client['id'] + @order_id = order_id + + order_href = "/orders/" + instance_variable_get("@order_id") + response = @client.post("/accounts/#{@customer_payable_account_id}/credits", { + amount: 10000, + order: order_href + }) + @client.add_hydrate "credit_id".to_sym, response['credits'][0]['id'] +end \ No newline at end of file diff --git a/features/step_definitions/orders.rb b/features/step_definitions/orders.rb index e1d62a7..edaeebe 100644 --- a/features/step_definitions/orders.rb +++ b/features/step_definitions/orders.rb @@ -77,7 +77,7 @@ amount: 10000, order: order_id }) - @client.add_hydrate :debit_id, @client['id'] + @client.add_hydrate ":debit_id_#{i + 1}", @client['id'] instance_variable_set("@order_id_#{i + 1}", order_id) end end \ No newline at end of file diff --git a/features/step_definitions/settlements.rb b/features/step_definitions/settlements.rb index 6cc6a12..731cce7 100644 --- a/features/step_definitions/settlements.rb +++ b/features/step_definitions/settlements.rb @@ -5,6 +5,8 @@ amount: 12345, order: @order_id }) + @credit_id = @client['credits']['id'] + @client.add_hydrate :credit_id, @credit_id @client.post("/accounts/#{@customer_payable_account_id}/settlements", { funding_instrument: :"/bank_accounts/#{@bank_account_id}" }) @@ -15,3 +17,12 @@ Given(/^I have (\d) settlements$/) do |num| num.to_i.times { step 'I have a bank account with a settlement' } end + + +Given(/^I settle the account$/) do + @client.post("/accounts/#{@customer_payable_account_id}/settlements", { + funding_instrument: :"/bank_accounts/#{@bank_account_id}" + }) + @settlement_id = @client['settlements']['id'] + @client.add_hydrate :settlement_id, @settlement_id +end From 2ff55e8ca956d7ef78e8889459a96ae63f109f9e Mon Sep 17 00:00:00 2001 From: richie serna Date: Fri, 12 Dec 2014 17:32:08 -0800 Subject: [PATCH 32/38] fix id for reversals feature: --- features/accounts.feature | 2 +- features/step_definitions/cards.rb | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/features/accounts.feature b/features/accounts.feature index 25cf831..53a8e15 100644 --- a/features/accounts.feature +++ b/features/accounts.feature @@ -94,7 +94,7 @@ Feature: Accounts """ { "links": { - "credit": ":credit_id_1" + "credit": ":credit_id" } } """ diff --git a/features/step_definitions/cards.rb b/features/step_definitions/cards.rb index 0932b56..1abd12c 100644 --- a/features/step_definitions/cards.rb +++ b/features/step_definitions/cards.rb @@ -7,7 +7,8 @@ cvv: "123", address: { line1: "965 Mission St", - postal_code: "94103" + postal_code: "94103", + city: "Balo Alto", } } ) From 8b81e3ec5b73ae7654bed1e3686d853dea7a165b Mon Sep 17 00:00:00 2001 From: richie serna Date: Mon, 15 Dec 2014 18:37:58 -0800 Subject: [PATCH 33/38] Edit checker in http_steps to evaluate nested entitites, such as events --- features/settlements.feature | 10 +++++++++- features/step_definitions/http_steps.rb | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/features/settlements.feature b/features/settlements.feature index 7ceed01..369a1f7 100644 --- a/features/settlements.feature +++ b/features/settlements.feature @@ -181,7 +181,15 @@ Scenario: Retrieving events for a settlement And the response is valid according to the "events" schema And the fields on these events match: """ - { "href": ":settlement_id" } + { + "entity": { + "settlements": { + "links": { + "source": ":customer_payable_account_id" + } + } + } + } """ Scenario: Retrieving source for a settlement diff --git a/features/step_definitions/http_steps.rb b/features/step_definitions/http_steps.rb index b28b177..acbecff 100644 --- a/features/step_definitions/http_steps.rb +++ b/features/step_definitions/http_steps.rb @@ -148,6 +148,8 @@ def checker(from, of, nesting) assert_equal val, of[key], "#{nesting}>#{key}" elsif val.nil? assert_nil of[key] + elsif of.is_a?(Array) + checker val, of[0][key], "#{nesting}>#{key}" else checker val, of[key], "#{nesting}>#{key}" end From 959a691d3bf3fb707c0c6086fe8861603e64f72e Mon Sep 17 00:00:00 2001 From: richie serna Date: Fri, 19 Dec 2014 13:52:07 -0800 Subject: [PATCH 34/38] add tests for negtive balances in account, change settlement schema to allow destinatin and source to be either bank account or account --- features/settlements.feature | 112 ++++++++++++++++++++++++++++++- fixtures/_models/settlement.json | 6 +- 2 files changed, 114 insertions(+), 4 deletions(-) diff --git a/features/settlements.feature b/features/settlements.feature index 369a1f7..89bb596 100644 --- a/features/settlements.feature +++ b/features/settlements.feature @@ -210,4 +210,114 @@ Scenario: Retrieving events for a settlement And the fields on this bank_account match: """ {"id": ":bank_account_id"} - """ \ No newline at end of file + """ + + Scenario: Create settlement with negative account balance from bank account + Given I have a bank account with a settlement + When I GET to /settlements/:settlement_id + Then I should get a 200 OK status code + And the response is valid according to the "settlements" schema + And the fields on this settlement match: + """ + { + "amount": 12345, + "appears_on_statement_as": "BAL*example.com" + } + """ + And I GET to /accounts/:customer_payable_account_id + Then I should get a 200 OK status code + And the fields on this account match: + """ + { + "balance": 0 + } + """ + And I POST to /credits/:credit_id/reversals + Then I should get a 201 CREATED status code + And the response is valid according to the "reversals" schema + And I GET to /accounts/:customer_payable_account_id + Then I should get a 200 OK status code + And the fields on this account match: + """ + { + "balance": -12345 + } + """ + When I POST to /accounts/:customer_payable_account_id/settlements with the body: + """ + { + "settlements": [{ + "funding_instrument": "/bank_accounts/:bank_account_id", + "appears_on_statement_as": "Settlement Oct", + "description": "Settlement for payouts from October" + }] + } + """ + Then I should get a 201 Created status code + And the response is valid according to the "settlements" schema + And the fields on this settlement match: + """ + { + "amount": 12345, + "appears_on_statement_as": "BAL*Settlement Oct", + "description": "Settlement for payouts from October", + "links": { + "destination": ":customer_payable_account_id" + } + } + """ + + And I GET to /accounts/:customer_payable_account_id + Then I should get a 200 OK status code + And the fields on this account match: + """ + { + "balance": 0 + } + """ + + Scenario: Settle an account with negative balance from another order + Given I have a bank account with a settlement + When I GET to /settlements/:settlement_id + Then I should get a 200 OK status code + And the response is valid according to the "settlements" schema + And the fields on this settlement match: + """ + { + "amount": 12345, + "appears_on_statement_as": "BAL*Settlement Oct", + "description": "Settlement for payouts from October", + "links": { + "destination": ":bank_account_id" + } + } + """ + + And I GET to /accounts/:customer_payable_account_id + Then I should get a 200 OK status code + And the fields on this account match: + """ + { + "balance": 0 + } + """ + And I POST to /credits/:credit_id/reversals + Then I should get a 201 CREATED status code + And the response is valid according to the "reversals" schema + And I GET to /accounts/:customer_payable_account_id + Then I should get a 200 OK status code + And the fields on this account match: + """ + { + "balance": -12345 + } + """ + And I have a bank account with a settlement + And I GET to /accounts/:customer_payable_account_id + Then I should get a 200 OK status code + And the fields on this account match: + """ + { + "balance": 0 + } + """ diff --git a/fixtures/_models/settlement.json b/fixtures/_models/settlement.json index e330d68..5a45cba 100644 --- a/fixtures/_models/settlement.json +++ b/fixtures/_models/settlement.json @@ -57,18 +57,18 @@ }, "transaction_number": { "type": "string", - "pattern": "SC[0-9A-Z]{3}-[0-9A-Z]{3}-[0-9A-Z]{4}" + "pattern": "(SC|SD)[0-9A-Z]{3}-[0-9A-Z]{3}-[0-9A-Z]{4}" }, "links": { "type": "object", "properties": { "destination": { "type": "string", - "pattern": "BA[a-zA-Z0-9]{16,32}" + "pattern": "(BA|AT)[a-zA-Z0-9]{16,32}" }, "source": { "type": "string", - "pattern": "AT[a-zA-Z0-9]{16,32}" + "pattern": "(BA|AT)[a-zA-Z0-9]{16,32}" } }, "required": [ From f75e3a074448717cb3d4747aa36c1fe3af45d5ae Mon Sep 17 00:00:00 2001 From: richie serna Date: Fri, 19 Dec 2014 13:52:52 -0800 Subject: [PATCH 35/38] Chnage bank account used to always transition to succeed --- features/step_definitions/bank_accounts.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/step_definitions/bank_accounts.rb b/features/step_definitions/bank_accounts.rb index 111b324..18fe02d 100644 --- a/features/step_definitions/bank_accounts.rb +++ b/features/step_definitions/bank_accounts.rb @@ -1,8 +1,8 @@ Given(/^I have tokenized a bank account$/) do @client.post('/bank_accounts', { name: "Henry Ford", - routing_number: "321174851", - account_number: "9900000001", + routing_number: "021000021", + account_number: "9900000002", account_type: "checking", }) @bank_account_id = @client['bank_accounts']['id'] From b5538eda69bb737e39aa9a1a9bcc2eda67ab8128 Mon Sep 17 00:00:00 2001 From: richie serna Date: Fri, 19 Dec 2014 14:47:13 -0800 Subject: [PATCH 36/38] fix status of bank account trasnactions --- features/debits.feature | 2 +- features/reversals.feature | 2 +- features/settlements.feature | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/debits.feature b/features/debits.feature index ef61a64..90fe995 100644 --- a/features/debits.feature +++ b/features/debits.feature @@ -162,7 +162,7 @@ Feature: Debit a card or bank account And the response is valid according to the "debits" schema And the fields on these debits match: """ - { "status": "pending" } + { "status": "succeeded" } """ Scenario: Debits to unverified bank accounts fail diff --git a/features/reversals.feature b/features/reversals.feature index 5f81381..df97859 100644 --- a/features/reversals.feature +++ b/features/reversals.feature @@ -193,7 +193,7 @@ Feature: Reversal """ { "amount": 30000, - "status": "pending" + "status": "succeeded" } """ diff --git a/features/settlements.feature b/features/settlements.feature index 89bb596..37d14b3 100644 --- a/features/settlements.feature +++ b/features/settlements.feature @@ -285,7 +285,7 @@ Scenario: Retrieving events for a settlement """ { "amount": 12345, - "appears_on_statement_as": "BAL*Settlement Oct", + "appears_on_statement_as": "BAL*example.com", "description": "Settlement for payouts from October", "links": { "destination": ":bank_account_id" From ec3af7035792bb4e08910be573e7eed3330bd652 Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Fri, 19 Dec 2014 17:16:12 -0700 Subject: [PATCH 37/38] Fixes --- features/reversals.feature | 19 +++++++++---------- features/settlements.feature | 3 +-- features/step_definitions/settlements.rb | 4 ++-- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/features/reversals.feature b/features/reversals.feature index df97859..1a3d2df 100644 --- a/features/reversals.feature +++ b/features/reversals.feature @@ -208,21 +208,20 @@ Feature: Reversal } """ - When POST to /accounts/:customer_payable_account_id/settlements - Then I should get a 201 Created status code - And the response is valid according to the "settlements" schema - - When I GET to /reversals/:reversal_id - Then I should get a 200 OK status code - And the response is valid according to the "reversals" schema - And the fields on this credit match: + When I POST to /accounts/:customer_payable_account_id/settlements with the body: """ - { "status": "succeeded" } + { + "settlements": [{ + "funding_instrument": "/bank_accounts/:bank_account_id" + }] + } """ + Then I should get a 201 Created status code + And the response is valid according to the "settlements" schema When I make a GET request to the link "reversals.order" Then I should get a 200 OK status code And the fields on this order match: """ - { "amount_escrowed": 1000 } + { "amount_escrowed": 10000 } """ diff --git a/features/settlements.feature b/features/settlements.feature index 37d14b3..745bf53 100644 --- a/features/settlements.feature +++ b/features/settlements.feature @@ -165,7 +165,7 @@ Feature: Settlements And the response is valid according to the "reversals" schema Then I settle the account When I GET to /settlements/:settlement_id/reversals - Then I should get a 200 OK status codek + Then I should get a 200 OK status code And the response is valid according to the "reversals" schema And the fields on these reversals match: """ @@ -286,7 +286,6 @@ Scenario: Retrieving events for a settlement { "amount": 12345, "appears_on_statement_as": "BAL*example.com", - "description": "Settlement for payouts from October", "links": { "destination": ":bank_account_id" } diff --git a/features/step_definitions/settlements.rb b/features/step_definitions/settlements.rb index 731cce7..30c12f8 100644 --- a/features/step_definitions/settlements.rb +++ b/features/step_definitions/settlements.rb @@ -8,8 +8,8 @@ @credit_id = @client['credits']['id'] @client.add_hydrate :credit_id, @credit_id @client.post("/accounts/#{@customer_payable_account_id}/settlements", { - funding_instrument: :"/bank_accounts/#{@bank_account_id}" - }) + funding_instrument: :"/bank_accounts/#{@bank_account_id}" + }) @settlement_id = @client['settlements']['id'] @client.add_hydrate :settlement_id, @settlement_id end From 08ad48ec45efaa449fad3a03b21359f83472a7bc Mon Sep 17 00:00:00 2001 From: Ben Mills Date: Fri, 19 Dec 2014 17:45:21 -0700 Subject: [PATCH 38/38] Fix parse error --- features/settlements.feature | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/features/settlements.feature b/features/settlements.feature index 745bf53..acb9d03 100644 --- a/features/settlements.feature +++ b/features/settlements.feature @@ -1,3 +1,4 @@ +@focus Feature: Settlements Settlement is the action of moving money out of an Account to a bank account. @@ -169,8 +170,10 @@ Feature: Settlements And the response is valid according to the "reversals" schema And the fields on these reversals match: """ - "links": { - "credit": ":credit_id" + { + "links": { + "credit": ":credit_id" + } } """