Skip to content

Commit

Permalink
Merge pull request #315 from recurly/purchases
Browse files Browse the repository at this point in the history
Purchases endpoint
  • Loading branch information
drewish committed May 31, 2017
2 parents c66cbd3 + 34de03f commit 23cb67a
Show file tree
Hide file tree
Showing 9 changed files with 417 additions and 7 deletions.
80 changes: 80 additions & 0 deletions Tests/Recurly/Purchase_Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

class Recurly_PurchaseTest extends Recurly_TestCase
{
function defaultResponses() {
return array(
array('POST', '/purchases', 'purchases/create-201.xml'),
array('POST', '/purchases/preview', 'purchases/preview-200.xml'),
);
}

public function mockPurchase() {
$purchase = new Recurly_Purchase();
$purchase->currency = 'USD';
$purchase->collection_method = 'automatic';
$purchase->account = new Recurly_Account();
$purchase->account->account_code = 'aba9209a-aa61-4790-8e61-0a2692435fee';
$purchase->account->address->phone = "555-555-5555";
$purchase->account->address->email = "verena@example.com";
$purchase->account->address->address1 = "123 Main St.";
$purchase->account->address->city = "San Francisco";
$purchase->account->address->state = "CA";
$purchase->account->address->zip = "94110";
$purchase->account->address->country = "US";

$adjustment = new Recurly_Adjustment();
$adjustment->product_code = "abcd123";
$adjustment->unit_amount_in_cents = 1000;
$adjustment->currency = 'USD';
$adjustment->quantity = 1;
$adjustment->revenue_schedule_type = 'at_invoice';

$purchase->adjustments[] = $adjustment;

return $purchase;
}

public function testXml() {
$purchase = $this->mockPurchase();

$this->assertEquals(
"<?xml version=\"1.0\"?>\n<purchase><account><account_code>aba9209a-aa61-4790-8e61-0a2692435fee</account_code><address><address1>123 Main St.</address1><city>San Francisco</city><state>CA</state><zip>94110</zip><country>US</country><phone>555-555-5555</phone></address></account><adjustments><adjustment><currency>USD</currency><unit_amount_in_cents>1000</unit_amount_in_cents><quantity>1</quantity><revenue_schedule_type>at_invoice</revenue_schedule_type><product_code>abcd123</product_code></adjustment></adjustments><collection_method>automatic</collection_method><currency>USD</currency></purchase>\n",
$purchase->xml()
);
}

public function testInvoicePurchase() {
$purchase = $this->mockPurchase();
$invoice = Recurly_Purchase::invoice($purchase, $this->client);

$this->assertInstanceOf('Recurly_Invoice', $invoice);
$this->assertEquals('3d8648fcf2be67ed304ff242d6bbb9d4', $invoice->uuid);
}

public function testPreviewPurchase() {
$purchase = $this->mockPurchase();
$invoice = Recurly_Purchase::preview($purchase, $this->client);

$this->assertInstanceOf('Recurly_Invoice', $invoice);
$this->assertNull($invoice->uuid);
}

public function testTransactionError() {
$this->client->addResponse('POST', '/purchases', 'purchases/create-422.xml');
$purchase = $this->mockPurchase();

try {
$invoice = Recurly_Purchase::invoice($purchase, $this->client);
$this->fail('Purchase should throw transaction exception but it threw no exception');
} catch (Recurly_ValidationError $e) {
$this->assertEquals($e->getMessage(), 'Credit card number is not valid.');
$this->assertInstanceOf('Recurly_TransactionError', $e->errors->transaction_error);
$this->assertInstanceOf('Recurly_Transaction', $e->errors->transaction);
} catch (Exception $e) {
print $e->getMessage();
$this->fail('Purchase should have thrown transaction exception');
}
}
}

27 changes: 21 additions & 6 deletions Tests/Recurly/ShippingAddress_Test.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?php


class Recurly_ShippingAddressTest extends Recurly_TestCase
{
function defaultResponses() {
Expand All @@ -9,12 +8,9 @@ function defaultResponses() {
);
}

public function testCreateShippingAddressOnExistingAccount() {
$account = Recurly_Account::get('abcdef1234567890', $this->client);
$this->client->addResponse('POST', 'https://api.recurly.com/v2/accounts/abcdef1234567890/shipping_addresses', 'shipping_addresses/create-201.xml');

protected function mockShippingAddress() {
$shad = new Recurly_ShippingAddress();
$shad->nickname = "Home";
$shad->nickname = "Work";
$shad->first_name = "Verena";
$shad->last_name = "Example";
$shad->phone = "555-555-5555";
Expand All @@ -24,6 +20,25 @@ public function testCreateShippingAddressOnExistingAccount() {
$shad->state = "CA";
$shad->zip = "94110";
$shad->country = "US";
$shad->company = "Recurly Inc.";

return $shad;
}

public function testXml() {
$shad = $this->mockShippingAddress();

$this->assertEquals(
"<?xml version=\"1.0\"?>\n<shipping_address><address1>123 Dolores St.</address1><city>San Francisco</city><state>CA</state><zip>94110</zip><country>US</country><phone>555-555-5555</phone><email>verena@example.com</email><nickname>Work</nickname><first_name>Verena</first_name><last_name>Example</last_name><company>Recurly Inc.</company></shipping_address>\n",
$shad->xml()
);
}

public function testCreateShippingAddressOnExistingAccount() {
$account = Recurly_Account::get('abcdef1234567890', $this->client);
$this->client->addResponse('POST', 'https://api.recurly.com/v2/accounts/abcdef1234567890/shipping_addresses', 'shipping_addresses/create-201.xml');

$shad = $this->mockShippingAddress();

$account->createShippingAddress($shad, $this->client);

Expand Down
124 changes: 124 additions & 0 deletions Tests/fixtures/purchases/create-201.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
HTTP/1.1 201 Created
Content-Type: application/xml; charset=utf-8
Location: https://api.recurly.com/v2/invoices/3704

<?xml version="1.0" encoding="UTF-8"?>
<invoice href="https://api.recurly.com/v2/invoices/3704">
<account href="https://api.recurly.com/v2/accounts/6b97ec05-7e9d-4506-a4b6-5459acbd6403"/>
<address>
<address1>400 Alabama St</address1>
<address2 nil="nil"></address2>
<city>San Francisco</city>
<state>CA</state>
<zip>94110</zip>
<country>US</country>
<phone nil="nil"></phone>
</address>
<uuid>3d8648fcf2be67ed304ff242d6bbb9d4</uuid>
<state>collected</state>
<invoice_number_prefix></invoice_number_prefix>
<invoice_number type="integer">3704</invoice_number>
<po_number nil="nil"></po_number>
<vat_number nil="nil"></vat_number>
<subtotal_in_cents type="integer">1000</subtotal_in_cents>
<tax_in_cents type="integer">0</tax_in_cents>
<total_in_cents type="integer">1000</total_in_cents>
<subtotal_after_discount_in_cents type="integer">1000</subtotal_after_discount_in_cents>
<currency>USD</currency>
<created_at type="datetime">2017-05-17T17:38:55Z</created_at>
<updated_at type="datetime">2017-05-17T17:38:55Z</updated_at>
<attempt_next_collection_at nil="nil"></attempt_next_collection_at>
<closed_at type="datetime">2017-05-17T17:38:55Z</closed_at>
<terms_and_conditions nil="nil"></terms_and_conditions>
<customer_notes nil="nil"></customer_notes>
<recovery_reason nil="nil"></recovery_reason>
<net_terms type="integer">0</net_terms>
<collection_method>automatic</collection_method>
<line_items type="array">
<adjustment href="https://api.recurly.com/v2/adjustments/3d8648fced80685b7f165a43fca65cda" type="charge">
<account href="https://api.recurly.com/v2/accounts/6b97ec05-7e9d-4506-a4b6-5459acbd6403"/>
<invoice href="https://api.recurly.com/v2/invoices/3704"/>
<uuid>3d8648fced80685b7f165a43fca65cda</uuid>
<state>invoiced</state>
<description nil="nil"></description>
<accounting_code nil="nil"></accounting_code>
<product_code>4549449c-5870-4845-b672-1d07f15e87dd</product_code>
<origin>debit</origin>
<unit_amount_in_cents type="integer">1000</unit_amount_in_cents>
<quantity type="integer">1</quantity>
<discount_in_cents type="integer">0</discount_in_cents>
<tax_in_cents type="integer">0</tax_in_cents>
<total_in_cents type="integer">1000</total_in_cents>
<currency>USD</currency>
<taxable type="boolean">false</taxable>
<tax_exempt type="boolean">false</tax_exempt>
<tax_code nil="nil"></tax_code>
<start_date type="datetime">2017-05-17T17:38:55Z</start_date>
<end_date nil="nil"></end_date>
<created_at type="datetime">2017-05-17T17:38:55Z</created_at>
<updated_at type="datetime">2017-05-17T17:38:55Z</updated_at>
<revenue_schedule_type>at_invoice</revenue_schedule_type>
</adjustment>
</line_items>
<transactions type="array">
<transaction href="https://api.recurly.com/v2/transactions/3d8648fd0cc7c6e9196b944878afcd3d" type="credit_card">
<account href="https://api.recurly.com/v2/accounts/6b97ec05-7e9d-4506-a4b6-5459acbd6403"/>
<invoice href="https://api.recurly.com/v2/invoices/3704"/>
<uuid>3d8648fd0cc7c6e9196b944878afcd3d</uuid>
<action>purchase</action>
<amount_in_cents type="integer">1000</amount_in_cents>
<tax_in_cents type="integer">0</tax_in_cents>
<currency>USD</currency>
<status>success</status>
<payment_method>credit_card</payment_method>
<reference>135998</reference>
<source>transaction</source>
<recurring type="boolean">false</recurring>
<test type="boolean">true</test>
<voidable type="boolean">true</voidable>
<refundable type="boolean">true</refundable>
<ip_address nil="nil"></ip_address>
<gateway_type>test</gateway_type>
<origin>api</origin>
<description nil="nil"></description>
<message>Successful test transaction</message>
<approval_code nil="nil"></approval_code>
<failure_type nil="nil"></failure_type>
<gateway_error_codes nil="nil"></gateway_error_codes>
<cvv_result code="" nil="nil"></cvv_result>
<avs_result code="D">Street address and postal code match.</avs_result>
<avs_result_street nil="nil"></avs_result_street>
<avs_result_postal nil="nil"></avs_result_postal>
<created_at type="datetime">2017-05-17T17:38:55Z</created_at>
<collected_at type="datetime">2017-05-17T17:38:55Z</collected_at>
<updated_at type="datetime">2017-05-17T17:38:55Z</updated_at>
<details>
<account>
<account_code>6b97ec05-7e9d-4506-a4b6-5459acbd6403</account_code>
<first_name nil="nil"></first_name>
<last_name nil="nil"></last_name>
<company nil="nil"></company>
<email nil="nil"></email>
<billing_info type="credit_card">
<first_name>Benjamin</first_name>
<last_name>Du Monde</last_name>
<address1>400 Alabama St</address1>
<address2 nil="nil"></address2>
<city>San Francisco</city>
<state>CA</state>
<zip>94110</zip>
<country>US</country>
<phone nil="nil"></phone>
<vat_number nil="nil"></vat_number>
<card_type>Visa</card_type>
<year type="integer">2019</year>
<month type="integer">12</month>
<first_six>411111</first_six>
<last_four>1111</last_four>
</billing_info>
</account>
</details>
</transaction>
</transactions>
<a name="refund" href="https://api.recurly.com/v2/invoices/3704/refund" method="post"/>
</invoice>
65 changes: 65 additions & 0 deletions Tests/fixtures/purchases/create-422.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/xml; charset=utf-8

<?xml version="1.0" encoding="UTF-8"?>
<errors>
<transaction_error>
<error_code>invalid_card_number</error_code>
<error_category>declined</error_category>
<customer_message lang="en-US">Your card number is not valid. Please update your card number.</customer_message>
<merchant_message lang="en-US">The credit card number is not valid. The customer needs to try a different number.</merchant_message>
<gateway_error_code>123</gateway_error_code>
</transaction_error>
<error field="transaction.account.billing_info.credit_card_number" symbol="invalid" lang="en-US">is not valid</error>
<transaction href="https://api.recurly.com/v2/transactions/abcdef1234567890">
<uuid>abcdef1234567890</uuid>
<action>purchase</action>
<amount_in_cents type="integer">100</amount_in_cents>
<tax_in_cents type="integer">0</tax_in_cents>
<currency>USD</currency>
<status>declined</status>
<reference nil="nil"></reference>
<test type="boolean">true</test>
<voidable type="boolean">false</voidable>
<refundable type="boolean">false</refundable>
<transaction_error>
<error_code>invalid_card_number</error_code>
<error_category>hard</error_category>
<merchant_message>The credit card number is not valid. The customer needs to try a different number.</merchant_message>
<customer_message>Your card number is not valid. Please update your card number.</customer_message>
<gateway_error_code>123</gateway_error_code>
</transaction_error>
<cvv_result code=""></cvv_result>
<avs_result code=""></avs_result>
<avs_result_street nil="nil"></avs_result_street>
<avs_result_postal nil="nil"></avs_result_postal>
<created_at type="datetime">2011-04-30T12:00:00Z</created_at>
<ip_address>127.0.0.1</ip_address>
<details>
<account>
<account_code>verena</account_code>
<first_name nil="nil"></first_name>
<last_name nil="nil"></last_name>
<company nil="nil"></company>
<email nil="nil"></email>
<billing_info type="credit_card">
<first_name nil="nil"></first_name>
<last_name nil="nil"></last_name>
<address1 nil="nil"></address1>
<address2 nil="nil"></address2>
<city nil="nil"></city>
<state nil="nil"></state>
<zip nil="nil"></zip>
<country nil="nil"></country>
<phone nil="nil"></phone>
<vat_number nil="nil"></vat_number>
<cc_type>visa</cc_type>
<year type="integer">2011</year>
<month type="integer">4</month>
<first_six>411111</first_six>
<last_four>1111</last_four>
</billing_info>
</account>
</details>
</transaction>
</errors>
64 changes: 64 additions & 0 deletions Tests/fixtures/purchases/preview-200.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
HTTP/1.1 200 OK
Content-Type: application/xml; charset=utf-8
Location: https://api.recurly.com/v2/invoices

<?xml version="1.0" encoding="UTF-8"?>
<invoice href="">
<account href="https://api.recurly.com/v2/accounts/c442b36c-c64f-41d7-b8e1-9c04e7a6ff82"/>
<address>
<address1>400 Alabama St</address1>
<address2 nil="nil"></address2>
<city>San Francisco</city>
<state>CA</state>
<zip>94110</zip>
<country>US</country>
<phone nil="nil"></phone>
</address>
<uuid nil="nil"></uuid>
<state>open</state>
<invoice_number_prefix></invoice_number_prefix>
<invoice_number nil="nil"></invoice_number>
<po_number nil="nil"></po_number>
<vat_number nil="nil"></vat_number>
<subtotal_in_cents type="integer">1000</subtotal_in_cents>
<tax_in_cents type="integer">0</tax_in_cents>
<total_in_cents type="integer">1000</total_in_cents>
<subtotal_after_discount_in_cents type="integer">1000</subtotal_after_discount_in_cents>
<currency>USD</currency>
<created_at nil="nil"></created_at>
<updated_at nil="nil"></updated_at>
<attempt_next_collection_at type="datetime">2017-05-17T16:36:56Z</attempt_next_collection_at>
<closed_at nil="nil"></closed_at>
<terms_and_conditions nil="nil"></terms_and_conditions>
<customer_notes nil="nil"></customer_notes>
<recovery_reason nil="nil"></recovery_reason>
<net_terms type="integer">0</net_terms>
<collection_method>automatic</collection_method>
<line_items type="array">
<adjustment href="" type="charge">
<account href="https://api.recurly.com/v2/accounts/c442b36c-c64f-41d7-b8e1-9c04e7a6ff82"/>
<uuid>3d86103d63f614d7aeee8341c98b2655</uuid>
<state>pending</state>
<description nil="nil"></description>
<accounting_code nil="nil"></accounting_code>
<product_code>4549449c-5870-4845-b672-1d07f15e87dd</product_code>
<origin>debit</origin>
<unit_amount_in_cents type="integer">1000</unit_amount_in_cents>
<quantity type="integer">1</quantity>
<discount_in_cents type="integer">0</discount_in_cents>
<tax_in_cents type="integer">0</tax_in_cents>
<total_in_cents type="integer">1000</total_in_cents>
<currency>USD</currency>
<taxable type="boolean">false</taxable>
<tax_exempt type="boolean">false</tax_exempt>
<tax_code nil="nil"></tax_code>
<start_date type="datetime">2017-05-17T16:36:56Z</start_date>
<end_date nil="nil"></end_date>
<created_at nil="nil"></created_at>
<updated_at nil="nil"></updated_at>
<revenue_schedule_type>at_invoice</revenue_schedule_type>
</adjustment>
</line_items>
<transactions type="array">
</transactions>
</invoice>
1 change: 1 addition & 0 deletions lib/recurly.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
require_once(dirname(__FILE__) . '/recurly/note_list.php');
require_once(dirname(__FILE__) . '/recurly/plan.php');
require_once(dirname(__FILE__) . '/recurly/plan_list.php');
require_once(dirname(__FILE__) . '/recurly/purchase.php');
require_once(dirname(__FILE__) . '/recurly/redemption.php');
require_once(dirname(__FILE__) . '/recurly/redemption_list.php');
require_once(dirname(__FILE__) . '/recurly/shipping_address.php');
Expand Down
Loading

0 comments on commit 23cb67a

Please sign in to comment.