Skip to content

fix post_customer() arguments #153

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions README.pod
Original file line number Diff line number Diff line change
Expand Up @@ -252,11 +252,11 @@ L<https://stripe.com/docs/api#create_customer>

=over

=item * customer - L<Net::Stripe::Customer> - existing customer to update, optional
=item * customer - L<Net::Stripe::Customer> or StripeCustomerId - existing customer to update, optional

=item * account_balance - Int, optional

=item * card - L<Net::Stripe::Card>, L<Net::Stripe::Token>, Str or HashRef, default card for the customer, optional
=item * card - L<Net::Stripe::Token>, StripeTokenId or HashRef, default card for the customer, optional

=item * coupon - Str, optional

Expand Down Expand Up @@ -1047,6 +1047,16 @@ paths and made the conditional structure more explicit, per discussion in
<https://github.com/lukec/stripe-perl/pull/133>. We also added unit tests
for all calling forms, per <https://github.com/lukec/stripe-perl/issues/139>.

=item fix post_customer() arguments

Some argument types for `card` are not legitimate and have been removed from
the Kavorka method signature. We removed `Net::Stripe::Card` and updated the
string validation to disallow card id for `card`, as neither of these are
legitimate when creating or updating a customer L<https://github.com/lukec/stripe-perl/issues/138>.
We have also updated the structure of the method so that we always create a
Net::Stripe::Customer object before posting L<https://github.com/lukec/stripe-perl/issues/148>
and cleaned up and centralized Net::Stripe:Token coercion code.

=back

=head1 SEE ALSO
Expand Down
51 changes: 28 additions & 23 deletions lib/Net/Stripe.pm
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,16 @@ paths and made the conditional structure more explicit, per discussion in
<https://github.com/lukec/stripe-perl/pull/133>. We also added unit tests
for all calling forms, per <https://github.com/lukec/stripe-perl/issues/139>.

=item fix post_customer() arguments

Some argument types for `card` are not legitimate and have been removed from
the Kavorka method signature. We removed `Net::Stripe::Card` and updated the
string validation to disallow card id for `card`, as neither of these are
legitimate when creating or updating a customer L<https://github.com/lukec/stripe-perl/issues/138>.
We have also updated the structure of the method so that we always create a
Net::Stripe::Customer object before posting L<https://github.com/lukec/stripe-perl/issues/148>
and cleaned up and centralized Net::Stripe:Token coercion code.

=back

=method new PARAMHASH
Expand Down Expand Up @@ -392,11 +402,11 @@ L<https://stripe.com/docs/api#create_customer>

=over

=item * customer - L<Net::Stripe::Customer> - existing customer to update, optional
=item * customer - L<Net::Stripe::Customer> or StripeCustomerId - existing customer to update, optional

=item * account_balance - Int, optional

=item * card - L<Net::Stripe::Card>, L<Net::Stripe::Token>, Str or HashRef, default card for the customer, optional
=item * card - L<Net::Stripe::Token>, StripeTokenId or HashRef, default card for the customer, optional

=item * coupon - Str, optional

Expand Down Expand Up @@ -499,9 +509,9 @@ Returns a L<Net::Stripe::List> object containing L<Net::Stripe::Customer> object
=cut

Customers: {
method post_customer(Net::Stripe::Customer|Str :$customer?,
method post_customer(Net::Stripe::Customer|StripeCustomerId :$customer?,
Int :$account_balance?,
Net::Stripe::Card|Net::Stripe::Token|Str|HashRef :$card?,
Net::Stripe::Token|StripeTokenId|HashRef :$card?,
Str :$coupon?,
Str :$default_card?,
Str :$description?,
Expand All @@ -511,36 +521,31 @@ Customers: {
Int :$quantity?,
Int|Str :$trial_end?) {

if (defined($card) && ref($card) eq 'HASH') {
$card = Net::Stripe::Card->new($card);
}

if (ref($customer) eq 'Net::Stripe::Customer') {
return $self->_post("customers/" . $customer->id, $customer);
} elsif (defined($customer)) {
my $customer_obj;
if ( ref( $customer ) ) {
$customer_obj = $customer;
} else {
my %args = (
account_balance => $account_balance,
card => $card,
coupon => $coupon,
default_card => $default_card,
email => $email,
metadata => $metadata,
plan => $plan,
quantity => $quantity,
trial_end => $trial_end,
);
$args{id} = $customer if defined( $customer );

return $self->_post("customers/" . $customer, \%args);
$customer_obj = Net::Stripe::Customer->new( %args );
}


$customer = Net::Stripe::Customer->new(account_balance => $account_balance,
card => $card,
coupon => $coupon,
description => $description,
email => $email,
metadata => $metadata,
plan => $plan,
quantity => $quantity,
trial_end => $trial_end);
return $self->_post('customers', $customer);
if ( my $customer_id = $customer_obj->id ) {
return $self->_post("customers/$customer_id", $customer_obj);
} else {
return $self->_post('customers', $customer_obj);
}
}

method list_subscriptions(Net::Stripe::Customer|Str :$customer,
Expand Down
5 changes: 2 additions & 3 deletions lib/Net/Stripe/Customer.pm
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extends 'Net::Stripe::Resource';
has 'email' => (is => 'rw', isa => 'Maybe[Str]');
has 'description' => (is => 'rw', isa => 'Maybe[Str]');
has 'trial_end' => (is => 'rw', isa => 'Maybe[Int|Str]');
has 'card' => (is => 'rw', isa => 'Maybe[Net::Stripe::Token|Net::Stripe::Card|Str]');
has 'card' => (is => 'rw', isa => 'Maybe[Net::Stripe::Token|Net::Stripe::Card|StripeTokenId]');
has 'quantity' => (is => 'rw', isa => 'Maybe[Int]');
has 'plan' => (is => 'rw', isa => 'Maybe[Net::Stripe::Plan|Str]');
has 'coupon' => (is => 'rw', isa => 'Maybe[Net::Stripe::Coupon|Str]');
Expand All @@ -41,8 +41,7 @@ sub _build_subscription {

method form_fields {
return (
(($self->card && ref($self->card) eq 'Net::Stripe::Token') ?
(card => $self->card->id) : $self->fields_for('card')),
$self->fields_for('card'),
$self->fields_for('plan'),
$self->fields_for('coupon'),
$self->form_fields_for_metadata(),
Expand Down
1 change: 1 addition & 0 deletions lib/Net/Stripe/Resource.pm
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ method fields_for($for) {
return unless $self->can($for);
my $thingy = $self->$for;
return unless $thingy;
return ($for => $thingy->id) if $for eq 'card' && ref($thingy) eq 'Net::Stripe::Token';
return $thingy->form_fields if ref($thingy) =~ m/^Net::Stripe::/;
return ($for => $thingy);
}
Expand Down
170 changes: 166 additions & 4 deletions t/live.t
Original file line number Diff line number Diff line change
Expand Up @@ -629,18 +629,180 @@ Customers: {
ok $customer->{deleted}, 'customer is now deleted';
}

Create_with_a_token: {
Create_with_a_token_id: {
my $token = $stripe->post_token(card => $fake_card);
my $customer = $stripe->post_customer(
card => $token->id,
);
isa_ok $customer, 'Net::Stripe::Customer', 'got back a customer';
ok $customer->id, 'customer has an id';
my $card = $stripe->get_card(
customer=> $customer,
card_id=> $customer->default_card,
customer => $customer,
card_id => $customer->default_card,
);
is $card->id, $token->card->id, 'token card id matches';
}

Create_with_a_token_object: {
my $token = $stripe->post_token(card => $fake_card);
my $customer = $stripe->post_customer(
card => $token,
);
isa_ok $customer, 'Net::Stripe::Customer', 'got back a customer';
ok $customer->id, 'customer has an id';
my $card = $stripe->get_card(
customer => $customer,
card_id => $customer->default_card,
);
is $card->id, $token->card->id, 'token card id matches';
}

Create_with_a_card_hashref: {
my $customer = $stripe->post_customer(
card => $fake_card,
);
isa_ok $customer, 'Net::Stripe::Customer', 'got back a customer';
ok $customer->id, 'customer has an id';
my $card = $stripe->get_card(
customer => $customer,
card_id => $customer->default_card,
);
is $card->last4, substr( $fake_card->{number}, -4 ), 'card last4 matches';
}

Update_card_for_customer_id_via_token_id: {
my $token = $stripe->post_token(card => $fake_card);
my $customer = $stripe->post_customer(
card => $token->id,
);
isa_ok $customer, 'Net::Stripe::Customer', 'got back a customer';
ok $customer->id, 'customer has an id';

my $cards = $stripe->get_cards(customer => $customer);
isa_ok $cards, "Net::Stripe::List";
is scalar @{$cards->data}, 1, 'customer has one card';
my $card = @{$cards->data}[0];
isa_ok $card, "Net::Stripe::Card";
is $card->id, $token->card->id, 'token card id matches';

my $new_token = $stripe->post_token(card => $fake_card);
$stripe->post_customer(
customer => $customer->id,
card => $new_token->id,
);
is $card->last4, '4242', 'card token ok';
$cards = $stripe->get_cards(customer => $customer);
isa_ok $cards, "Net::Stripe::List";
is scalar @{$cards->data}, 1, 'customer still has one card';
my $new_card = @{$cards->data}[0];
is $new_card->id, $new_token->card->id, 'new token card id matches';
isnt $new_card->id, $card->id, 'new card has different card id';
}

Update_card_for_customer_object_via_token_id: {
my $token = $stripe->post_token(card => $fake_card);
my $customer = $stripe->post_customer(
card => $token->id,
);
isa_ok $customer, 'Net::Stripe::Customer', 'got back a customer';
ok $customer->id, 'customer has an id';

my $cards = $stripe->get_cards(customer => $customer);
isa_ok $cards, "Net::Stripe::List";
is scalar @{$cards->data}, 1, 'customer has one card';
my $card = @{$cards->data}[0];
isa_ok $card, "Net::Stripe::Card";
is $card->id, $token->card->id, 'token card id matches';

my $new_token = $stripe->post_token(card => $fake_card);
$customer->card($new_token->id);
$stripe->post_customer(customer => $customer);
$cards = $stripe->get_cards(customer => $customer);
isa_ok $cards, "Net::Stripe::List";
is scalar @{$cards->data}, 1, 'customer still has one card';
my $new_card = @{$cards->data}[0];
is $new_card->id, $new_token->card->id, 'new token card id matches';
isnt $new_card->id, $card->id, 'new card has different card id';
}

Update_card_for_customer_id_via_card_hashref: {
my $token = $stripe->post_token(card => $fake_card);
my $customer = $stripe->post_customer(
card => $token->id,
);
isa_ok $customer, 'Net::Stripe::Customer', 'got back a customer';
ok $customer->id, 'customer has an id';

my $cards = $stripe->get_cards(customer => $customer);
isa_ok $cards, "Net::Stripe::List";
is scalar @{$cards->data}, 1, 'customer has one card';
my $card = @{$cards->data}[0];
isa_ok $card, "Net::Stripe::Card";
is $card->id, $token->card->id, 'token card id matches';

$stripe->post_customer(
customer => $customer->id,
card => $fake_card,
);
$cards = $stripe->get_cards(customer => $customer);
isa_ok $cards, "Net::Stripe::List";
is scalar @{$cards->data}, 1, 'customer still has one card';
my $new_card = @{$cards->data}[0];
is $new_card->last4, substr( $fake_card->{number}, -4 ), 'new card last4 matches';
isnt $new_card->id, $card->id, 'new card has different card id';
}

Update_card_for_customer_id_via_token_object: {
my $token = $stripe->post_token(card => $fake_card);
my $customer = $stripe->post_customer(
card => $token->id,
);
isa_ok $customer, 'Net::Stripe::Customer', 'got back a customer';
ok $customer->id, 'customer has an id';

my $cards = $stripe->get_cards(customer => $customer);
isa_ok $cards, "Net::Stripe::List";
is scalar @{$cards->data}, 1, 'customer has one card';
my $card = @{$cards->data}[0];
isa_ok $card, "Net::Stripe::Card";
is $card->id, $token->card->id, 'token card id matches';

my $new_token = $stripe->post_token(card => $fake_card);
$stripe->post_customer(
customer => $customer->id,
card => $new_token,
);
$cards = $stripe->get_cards(customer => $customer);
isa_ok $cards, "Net::Stripe::List";
is scalar @{$cards->data}, 1, 'customer still has one card';
my $new_card = @{$cards->data}[0];
is $new_card->id, $new_token->card->id, 'new token card id matches';
isnt $new_card->id, $card->id, 'new card has different card id';
}

Update_card_for_customer_object_via_token_object: {
my $token = $stripe->post_token(card => $fake_card);
my $customer = $stripe->post_customer(
card => $token->id,
);
isa_ok $customer, 'Net::Stripe::Customer', 'got back a customer';
ok $customer->id, 'customer has an id';

my $cards = $stripe->get_cards(customer => $customer);
isa_ok $cards, "Net::Stripe::List";
is scalar @{$cards->data}, 1, 'customer has one card';
my $card = @{$cards->data}[0];
isa_ok $card, "Net::Stripe::Card";
is $card->id, $token->card->id, 'token card id matches';

my $new_token = $stripe->post_token(card => $fake_card);
$customer->card($new_token);
$stripe->post_customer(customer => $customer);
$cards = $stripe->get_cards(customer => $customer);
isa_ok $cards, "Net::Stripe::List";
is scalar @{$cards->data}, 1, 'customer still has one card';
my $new_card = @{$cards->data}[0];
is $new_card->id, $new_token->card->id, 'new token card id matches';
isnt $new_card->id, $card->id, 'new card has different card id';
}

Add_card_for_customer_object_via_token_id: {
Expand Down