From 439f8962d1399aecb94639d3697b237fda04d84c Mon Sep 17 00:00:00 2001 From: Chris Harvey Date: Tue, 12 Feb 2019 12:47:18 +0000 Subject: [PATCH 1/2] Add the ability to update a charge --- src/Gateway.php | 14 ++++++++ src/Message/UpdateChargeRequest.php | 50 +++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/Message/UpdateChargeRequest.php diff --git a/src/Gateway.php b/src/Gateway.php index b0532e55..d768a76d 100644 --- a/src/Gateway.php +++ b/src/Gateway.php @@ -219,6 +219,20 @@ public function purchase(array $parameters = array()) return $this->createRequest('\Omnipay\Stripe\Message\PurchaseRequest', $parameters); } + /** + * Update charge request. + * + * Update the data for a charge after the charge has been created. + * + * @param array $parameters + * + * @return \Omnipay\Stripe\Message\Response + */ + public function updateCharge(array $parameters = array()) + { + return $this->createRequest('\Omnipay\Stripe\Message\UpdateChargeRequest', $parameters); + } + /** * Refund Request. * diff --git a/src/Message/UpdateChargeRequest.php b/src/Message/UpdateChargeRequest.php new file mode 100644 index 00000000..63daab60 --- /dev/null +++ b/src/Message/UpdateChargeRequest.php @@ -0,0 +1,50 @@ +validate('transactionReference'); + + $data = array(); + + if ($this->getDescription()) { + $data['description'] = $this->getDescription(); + } + + if ($this->getCustomerReference()) { + $data['customer'] = $this->getCustomerReference(); + } + + if ($this->getMetadata()) { + $data['metadata'] = $this->getMetadata(); + } + + if ($this->getReceiptEmail()) { + $data['receipt_email'] = $this->getReceiptEmail(); + } + + if ($this->getTransferGroup()) { + $data['transfer_group'] = $this->getTransferGroup(); + } + + // Filter out the empty/non-updated values + return $data; + } + + public function getEndpoint() + { + return $this->endpoint.'/charges/'.$this->getTransactionReference(); + } +} From a8f5c4dec31cc6ee6c84cc84d9c81f253bcc8a1b Mon Sep 17 00:00:00 2001 From: Chris Harvey Date: Tue, 12 Feb 2019 12:47:55 +0000 Subject: [PATCH 2/2] Add tests for update charge --- tests/Message/UpdateChargeRequestTest.php | 61 +++++++++++++ tests/Mock/UpdateChargeFailure.txt | 19 ++++ tests/Mock/UpdateChargeSuccess.txt | 104 ++++++++++++++++++++++ 3 files changed, 184 insertions(+) create mode 100644 tests/Message/UpdateChargeRequestTest.php create mode 100644 tests/Mock/UpdateChargeFailure.txt create mode 100644 tests/Mock/UpdateChargeSuccess.txt diff --git a/tests/Message/UpdateChargeRequestTest.php b/tests/Message/UpdateChargeRequestTest.php new file mode 100644 index 00000000..89b1871b --- /dev/null +++ b/tests/Message/UpdateChargeRequestTest.php @@ -0,0 +1,61 @@ +request = new UpdateChargeRequest($this->getHttpClient(), $this->getHttpRequest()); + $this->request->setTransactionReference('foo'); + } + + public function testEndpoint() + { + $this->assertSame('https://api.stripe.com/v1/charges/foo', $this->request->getEndpoint()); + } + + public function testData() + { + $this->request->setDescription('New customer'); + $this->request->setCustomerReference('cus_1MZeNih5LdKxDq'); + $this->request->setReceiptEmail('customer@business.dom'); + $this->request->setTransferGroup('test'); + $this->request->setMetadata(array('field' => 'value')); + + $data = $this->request->getData(); + + $this->assertSame('cus_1MZeNih5LdKxDq', $data['customer']); + $this->assertSame('customer@business.dom', $data['receipt_email']); + $this->assertSame('New customer', $data['description']); + $this->assertArrayHasKey('field', $data['metadata']); + $this->assertSame('value', $data['metadata']['field']); + $this->assertSame('test', $data['transfer_group']); + } + + public function testSendSuccess() + { + $this->setMockHttpResponse('UpdateChargeSuccess.txt'); + $response = $this->request->send(); + + $this->assertTrue($response->isSuccessful()); + $this->assertFalse($response->isRedirect()); + $this->assertSame('ch_1E0Pt92eZvKYlo2C05QSmQvw', $response->getTransactionReference()); + $this->assertSame('cus_1MZeNih5LdKxDq', $response->getCustomerReference()); + $this->assertNull($response->getMessage()); + } + + public function testSendFailure() + { + $this->setMockHttpResponse('UpdateChargeFailure.txt'); + $response = $this->request->send(); + + $this->assertFalse($response->isSuccessful()); + $this->assertFalse($response->isRedirect()); + $this->assertNull($response->getTransactionReference()); + $this->assertNull($response->getCustomerReference()); + $this->assertSame('No such charge: ch_1E0Pt92eZvKYlo2C0QSmQvw', $response->getMessage()); + } +} diff --git a/tests/Mock/UpdateChargeFailure.txt b/tests/Mock/UpdateChargeFailure.txt new file mode 100644 index 00000000..308a597c --- /dev/null +++ b/tests/Mock/UpdateChargeFailure.txt @@ -0,0 +1,19 @@ +HTTP/1.1 400 Bad Request +Server: nginx +Date: Sun, 05 May 2013 08:52:09 GMT +Content-Type: application/json;charset=utf-8 +Content-Length: 127 +Connection: keep-alive +Cache-Control: no-cache, no-store +Access-Control-Max-Age: 300 +Access-Control-Allow-Credentials: true + +{ + "error": { + "code": "resource_missing", + "doc_url": "https://stripe.com/docs/error-codes/resource-missing", + "message": "No such charge: ch_1E0Pt92eZvKYlo2C0QSmQvw", + "param": "id", + "type": "invalid_request_error" + } +} diff --git a/tests/Mock/UpdateChargeSuccess.txt b/tests/Mock/UpdateChargeSuccess.txt new file mode 100644 index 00000000..95bbf8bc --- /dev/null +++ b/tests/Mock/UpdateChargeSuccess.txt @@ -0,0 +1,104 @@ +HTTP/1.1 200 OK +Server: nginx +Date: Sun, 05 May 2013 08:51:15 GMT +Content-Type: application/json;charset=utf-8 +Content-Length: 997 +Connection: keep-alive +Cache-Control: no-cache, no-store +Access-Control-Max-Age: 300 +Access-Control-Allow-Credentials: true + +{ + "id": "ch_1E0Pt92eZvKYlo2C05QSmQvw", + "object": "charge", + "amount": 1000, + "amount_refunded": 0, + "application": null, + "application_fee": null, + "application_fee_amount": null, + "balance_transaction": "txn_19XJJ02eZvKYlo2ClwuJ1rbA", + "captured": false, + "created": 1549357603, + "currency": "usd", + "customer": "cus_1MZeNih5LdKxDq", + "description": "Test", + "destination": null, + "dispute": null, + "failure_code": "card_declined", + "failure_message": "Your card was declined.", + "fraud_details": {}, + "invoice": null, + "livemode": false, + "metadata": {}, + "on_behalf_of": null, + "order": null, + "outcome": { + "network_status": "not_sent_to_network", + "reason": "highest_risk_level", + "risk_level": "highest", + "risk_score": 96, + "rule": "block_if_high_risk", + "seller_message": "Stripe blocked this payment as too risky.", + "type": "blocked" + }, + "paid": false, + "payment_intent": null, + "payment_method": null, + "payment_method_details": { + "card": { + "brand": "Visa", + "country": "US", + "dynamic_last4": null, + "exp_month": 12, + "exp_year": 2031, + "fingerprint": "yTFMYiPXiPa5AoSn", + "funding": "credit", + "last4": "4954", + "three_d_secure": null + }, + "type": "card" + }, + "receipt_email": null, + "receipt_number": "1431-2893", + "receipt_url": "https://pay.stripe.com/receipts/acct_1032D82eZvKYlo2C/ch_1E0Pt92eZvKYlo2C05QSmQvw/rcpt_ETMcXQkHm68RMJztwqc6DDKAdCm8QR7", + "refunded": false, + "refunds": { + "object": "list", + "data": [], + "has_more": false, + "total_count": 0, + "url": "/v1/charges/ch_1E0Pt92eZvKYlo2C05QSmQvw/refunds" + }, + "review": null, + "shipping": null, + "source": { + "id": "card_1E0Pt52eZvKYlo2Czz19lZi3", + "object": "card", + "address_city": null, + "address_country": null, + "address_line1": null, + "address_line1_check": null, + "address_line2": null, + "address_state": null, + "address_zip": "12345", + "address_zip_check": "unavailable", + "brand": "Visa", + "country": "US", + "customer": null, + "cvc_check": "unavailable", + "dynamic_last4": null, + "exp_month": 12, + "exp_year": 2031, + "fingerprint": "yTFMYiPXiPa5AoSn", + "funding": "credit", + "last4": "4954", + "metadata": {}, + "name": "ex@mail.ru", + "tokenization_method": null + }, + "source_transfer": null, + "statement_descriptor": null, + "status": "failed", + "transfer_data": null, + "transfer_group": null +} \ No newline at end of file