Skip to content

Commit

Permalink
Support Transfer Reversals (#20)
Browse files Browse the repository at this point in the history
Adds support for reversing existing transfers via a new create_reversal method. This method accepts three arguments:

- (Required) The transfer ID - any stringifiable value
- (Optional) Reversal data - a hashref defaulting to {}
- (Optional) Options - a hashref defaulting to {}. Right now the only valid key is 'headers', which is passed verbatim to the LWP::UserAgent as request headers.

The method signature ($id, $data = {}, $opts = {}) is meant as a template for all methods that act on a single, existing object. Right now, WS::Stripe uses a mix of positional and named parameters that is not consistent and requires looking back at the documentation. We should unify these signatures to promote understanding. For operations involving new objects, I'd propose the very-similar signature ($data, $opts = {}).
  • Loading branch information
danschmidt5189 committed Jul 13, 2015
1 parent 9d0a6bf commit 6d07261
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 11 deletions.
29 changes: 29 additions & 0 deletions lib/WebService/Stripe.pm
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,12 @@ method cancel_transfer(Str $id, :$headers) {
return $self->post("/v1/transfers/$id/cancel", undef, headers => $headers);
}

method create_reversal($xfer_id, HashRef $data = {}, HashRef $opts = {}) {
return $self->post("/v1/transfers/$xfer_id/reversals", $data,
headers => $opts->{'headers'} // {},
);
}

method get_bitcoin_receivers(HashRef :$query, :$headers) {
return $self->get( "/v1/bitcoin/receivers", $query, headers => $headers );
}
Expand Down Expand Up @@ -428,6 +434,29 @@ Example:
cancel_transfer($id)
=head2 create_reversal
Reverses an existing transfer.
Example 1 - Custom Body + Headers:
# W/Custom Body + Headers
$ws_stripe->create_reversal(xfer_id, {
refund_application_fee => 'true'
}, {
headers => { 'Stripe-Account' => $account->{'id'} }
});
Example 2 - Custom Headers, only:
$ws_stripe->create_reversal(xfer_id, {}, {
headers => { 'Stripe-Account' => $account->{'id'} },
});
Example 3 - Defaults:
$ws_stripe->create_reversal(xfer_id);
=head2 get_balance
get_balance()
Expand Down
81 changes: 70 additions & 11 deletions t/04-transfers.t
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use Test::Modern;
use Test::Modern qw(:deeper :fatal :more);
use t::lib::Common qw(:constants skip_unless_has_secret stripe);
use JSON qw(from_json);

Expand All @@ -17,39 +17,98 @@ my $bank = stripe->add_bank(
},
account_id => $account->{id},
);
cmp_deeply $bank => TD->superhashof({ last4 => 6789 }), 'created bank';
cmp_deeply $bank => superhashof({ last4 => 6789 }), 'created bank';

subtest 'create a transfer and do stuff with it' => sub {
my $transfer = stripe->create_transfer({
amount => 100,
currency => 'cad',
destination => $account->{id},
});
cmp_deeply $transfer => TD->superhashof({
id => TD->re('^tr_'),
cmp_deeply $transfer => superhashof({
id => re('^tr_'),
amount => 100,
});
my $transfer_id = $transfer->{id};
}),
'... Created a transfer';

my $transfer_id = $transfer->{id};
$transfer = stripe->update_transfer($transfer->{id}, data => {
'metadata[foo]' => 'bar'
});
is $transfer->{id} => $transfer_id;
is $transfer->{id}, $transfer_id,
'... Updated a transfer';

$transfer = stripe->get_transfer($transfer->{id});
cmp_deeply $transfer => TD->superhashof({
cmp_deeply $transfer => superhashof({
id => $transfer_id,
amount => 100,
metadata => { foo => 'bar' },
});
}),
'... Got an existing transfer';

my $exc = exception { stripe->cancel_transfer($transfer->{id}) };
is $exc->code => 400;
# Expect failure b/c Stripe's test env doesn't support this
my $err = exception { stripe->cancel_transfer($transfer->{id}) };
like $err, qr/while they are pending/,
'... Sent cancel request to Stripe';
};

subtest 'list transfers' => sub {
my $transfers = stripe->get_transfers;
ok $transfers->{data}[0]{amount};
};

subtest 'create_reversal' => sub {
subtest "Can create a complete reversal" => sub {
my $xfer = stripe->create_transfer({
amount => 100,
currency => 'cad',
destination => $account->{'id'},
'metadata[tester]' => 'WebService::Stripe::create_reversal',
});

my $reversal = stripe->create_reversal($xfer->{'id'});
cmp_deeply $reversal, superhashof({
object => 'transfer_reversal',
amount => 100,
}),
'... Created a full reversal',
or diag explain $reversal;
};

subtest "Can create a partial reversal" => sub {
my $xfer = stripe->create_transfer({
amount => 50,
currency => 'cad',
destination => $account->{'id'},
});

my $reversal = stripe->create_reversal($xfer->{'id'});
cmp_deeply $reversal, superhashof({
object => 'transfer_reversal',
amount => 50,
}),
'... Created a 50% reversal',
or diag explain $reversal;
};

subtest "Can reverse an Account-scoped bank transfer" => sub {
my %headers = (headers => { stripe_account => $account->{'id'} });
my $xfer = stripe->create_transfer({
amount => 50,
currency => 'cad',
destination => $bank->{'id'},
}, %headers);

my $err = exception {
stripe->create_reversal($xfer->{'id'}, {
amount => 25,
}, { %headers });
};

# Expect failure b/c Stripe's test environment doesn't support this
like $err, qr/while they are pending/,
'... Sent reversal request to Stripe';
};
};

done_testing;

0 comments on commit 6d07261

Please sign in to comment.