diff --git a/dist/js/tool.js b/dist/js/tool.js index 9ea223a..34ac37f 100644 --- a/dist/js/tool.js +++ b/dist/js/tool.js @@ -2866,14 +2866,49 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); // // // +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// /* harmony default export */ __webpack_exports__["default"] = ({ props: ['chargeId'], - components: { 'charge-detail-card': __WEBPACK_IMPORTED_MODULE_0__components_ChargeDetailCard_vue___default.a + }, + data: function data() { + return { + charge: undefined, + deleting: false + }; + }, + + methods: { + refund: function refund(chargeId) { + var _this = this; + + this.deleting = true; + + Nova.request().post('/nova-vendor/nova-stripe/stripe/charges/' + this.chargeId + '/refund').then(function (response) { + Nova.success('Charge Successfully Refunded!'); + _this.$refs.detail.getCharge(); + }); + + this.deleting = false; + } } }); @@ -2996,6 +3031,7 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); Nova.request().get('/nova-vendor/nova-stripe/stripe/charges/' + this.chargeId).then(function (response) { _this.charge = response.data.charge; _this.initialLoading = false; + _this.$emit('charge-loaded', response.data.charge); }); }, formatMoney: function formatMoney(amount, currency) { @@ -3106,7 +3142,33 @@ var render = function() { [ _c("heading", { staticClass: "mb-6" }, [_vm._v("Charge Details")]), _vm._v(" "), - _c("charge-detail-card", { attrs: { "charge-id": _vm.chargeId } }) + _c("div", { staticClass: "flex flex-row-reverse mb-3" }, [ + _vm.charge && !_vm.charge.refunded + ? _c( + "button", + { + staticClass: "btn-primary px-4 py-2 rounded", + attrs: { disabled: _vm.deleting }, + on: { + click: function($event) { + return _vm.refund(_vm.charge.id) + } + } + }, + [_vm._v("\n Refund\n ")] + ) + : _vm._e() + ]), + _vm._v(" "), + _c("charge-detail-card", { + ref: "detail", + attrs: { "charge-id": _vm.chargeId }, + on: { + "charge-loaded": function($event) { + _vm.charge = $event + } + } + }) ], 1 ) diff --git a/package.json b/package.json index 7db08ee..c9babcf 100644 --- a/package.json +++ b/package.json @@ -16,5 +16,11 @@ "dependencies": { "currency.js": "^1.2.1", "vue": "^2.5.0" + }, + "prettier": { + "singleQuote": true, + "trailingComma": "es5", + "tabWidth": 4, + "printWidth": 80 } } diff --git a/resources/js/components/ChargeDetailCard.vue b/resources/js/components/ChargeDetailCard.vue index 92e96ed..f6413fc 100644 --- a/resources/js/components/ChargeDetailCard.vue +++ b/resources/js/components/ChargeDetailCard.vue @@ -65,6 +65,7 @@ export default { .then((response) => { this.charge = response.data.charge this.initialLoading = false + this.$emit('charge-loaded', response.data.charge); }) }, diff --git a/resources/js/views/Detail.vue b/resources/js/views/Detail.vue index 93a56e9..1f550ed 100644 --- a/resources/js/views/Detail.vue +++ b/resources/js/views/Detail.vue @@ -2,18 +2,56 @@
Charge Details - +
+ +
+ +
diff --git a/routes/api.php b/routes/api.php index 24befcf..ddc57aa 100644 --- a/routes/api.php +++ b/routes/api.php @@ -18,4 +18,5 @@ Route::get('/stripe/charges', StripeChargesController::class . '@index'); Route::get('/stripe/charges/{id}', StripeChargesController::class . '@show'); +Route::post('/stripe/charges/{id}/refund', StripeChargesController::class . '@refund'); Route::get('/stripe/balance', StripeBalanceController::class . '@index'); diff --git a/src/Clients/StripeClient.php b/src/Clients/StripeClient.php index be127d7..394c00d 100644 --- a/src/Clients/StripeClient.php +++ b/src/Clients/StripeClient.php @@ -5,6 +5,7 @@ use Exception; use Stripe\Balance; use Stripe\Charge; +use Stripe\Refund; class StripeClient { @@ -52,4 +53,22 @@ public function getBalance() } } + + public function refundCharge($chargeId) + { + try { + return Refund::create(['charge' => $chargeId], ['api_key' => $this->apiKey]); + } catch (Exception $e) { + + } + } + + public function createCharge(array $params) + { + try { + return Charge::create($params, ['api_key' => $this->apiKey]); + } catch (Exception $e) { + + } + } } diff --git a/src/Http/StripeChargesController.php b/src/Http/StripeChargesController.php index 7da0c60..b9eef91 100644 --- a/src/Http/StripeChargesController.php +++ b/src/Http/StripeChargesController.php @@ -3,6 +3,7 @@ namespace Tighten\NovaStripe\Http; use Illuminate\Routing\Controller; +use Stripe\Charge; use Tighten\NovaStripe\Clients\StripeClient; class StripeChargesController extends Controller @@ -20,4 +21,9 @@ public function show($id) { return response()->json(['charge' => (new StripeClient)->getCharge($id)]); } + + public function refund($id) + { + return response()->json((new StripeClient)->refundCharge($id)); + } } diff --git a/tests/StripeChargeControllerTest.php b/tests/StripeChargeControllerTest.php index 96377b8..b13dd3e 100644 --- a/tests/StripeChargeControllerTest.php +++ b/tests/StripeChargeControllerTest.php @@ -3,9 +3,7 @@ namespace Tighten\NovaStripe\Tests; use Illuminate\Foundation\Testing\WithFaker; -use Illuminate\Support\Facades\Config; -use Stripe\Charge; -use Stripe\StripeClient; +use Tighten\NovaStripe\Clients\StripeClient; class StripeChargeControllerTest extends TestCase { @@ -17,11 +15,10 @@ class StripeChargeControllerTest extends TestCase public function setUp(): void { parent::setUp(); - $this->stripe = new StripeClient(Config::get('services.stripe.secret')); + $this->stripe = new StripeClient; - $this->charge = $this->stripe->charges->all()->count() - ? $this->stripe->charges->all(['limit' => 1])->first() - : $this->stripe->charges->create([ + $this->charge = $this->findSuccessfulNonRefundedCharge() + ?: $this->stripe->createCharge([ 'amount' => $this->faker->numberBetween(50, 1000), 'currency' => 'usd', 'source' => 'tok_mastercard', @@ -54,7 +51,7 @@ public function it_returns_a_list_of_charges() public function it_returns_charge_details() { $response = $this->get('nova-vendor/nova-stripe/stripe/charges/' . $this->charge->id); - $stripeCharge = Charge::retrieve(['id' => $this->charge->id, 'expand' => ['balance_transaction']], ['api_key' => Config::get('services.stripe.secret')]); + $stripeCharge = $this->stripe->getCharge($this->charge->id); $response->assertJsonFragment([ 'id' => $stripeCharge->id, @@ -86,7 +83,7 @@ public function it_returns_charge_details() /** @test */ public function it_shows_the_current_balance() { - $balance = $this->stripe->balance->retrieve(); + $balance = $this->stripe->getBalance(); $this->get('nova-vendor/nova-stripe/stripe/balance') ->assertJsonFragment([ @@ -94,4 +91,30 @@ public function it_shows_the_current_balance() 'pending' => $balance->pending, ]); } + + /** @test */ + public function it_can_refund_a_charge_successfully() + { + $this->post('nova-vendor/nova-stripe/stripe/charges/' . $this->charge->id . '/refund') + ->assertSuccessful() + ->assertJsonFragment([ + 'charge' => $this->charge->id, + 'status' => 'succeeded', + ]); + + $this->assertTrue($this->stripe->getCharge($this->charge->id)->refunded); + } + + public function findSuccessfulNonRefundedCharge() + { + $charges = $this->stripe->listCharges(); + + foreach ($charges as $charge) { + if (! $charge->refunded && $charge->status === 'succeeded') { + return $charge; + } + } + + return null; + } }