Skip to content

Commit b173b9a

Browse files
committed
Merge pull request #133 from sherrardb/f-cannot-update-existing-card
allow updates to existing cards
2 parents 646861d + 4d9c267 commit b173b9a

File tree

3 files changed

+112
-1
lines changed

3 files changed

+112
-1
lines changed

lib/Net/Stripe.pm

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,18 @@ a card object. We have also added TypeConstraints for the string arguments
102102
passed and added in-method validation to ensure that the passed argument
103103
values make sense in the context of one another.
104104
105+
=item add update_card()
106+
This method allows updates to card address, expiration, metadata, etc for
107+
existing customer cards.
108+
109+
=item encode card metdata in convert_to_form_fields()
110+
111+
When passing a hashref with a nested metadata hashref to _post(), that
112+
metadata must be encoded properly before being passed to the Stripe API.
113+
There is now a dedicated block in convert_to_form_fields for this operation.
114+
This update was necessary because of the addition of update_card(), which
115+
accepts a card hashref, which may include metadata.
116+
105117
=back
106118
107119
=method new PARAMHASH
@@ -576,6 +588,35 @@ Returns a L<Net::Stripe::Card>.
576588
577589
$stripe->create_card(customer => $customer, card => $card);
578590
591+
=card_method update_card
592+
593+
Update a card.
594+
595+
L<https://stripe.com/docs/api/cards/update#update_card>
596+
597+
=over
598+
599+
=item * customer_id - L<StripeCustomerId>
600+
601+
=item * card_id - L<StripeCardId>
602+
603+
=item * card - HashRef
604+
605+
=back
606+
607+
Returns a L<Net::Stripe::Card>.
608+
609+
$stripe->update_card(
610+
customer_id => $customer_id,
611+
card_id => $card_id,
612+
card => {
613+
name => $new_name,
614+
metadata => {
615+
'account-number' => $new_account_nunmber,
616+
},
617+
},
618+
);
619+
579620
=card_method get_cards
580621
581622
Returns a list of cards.
@@ -668,6 +709,12 @@ Cards: {
668709
return $self->_post("customers/$customer/cards", $card);
669710
}
670711

712+
method update_card(StripeCustomerId :$customer_id!,
713+
StripeCardId :$card_id!,
714+
HashRef :$card!) {
715+
return $self->_post("customers/$customer_id/cards/$card_id", $card);
716+
}
717+
671718
method delete_card(Net::Stripe::Customer|Str :$customer, Net::Stripe::Card|Str :$card) {
672719
if (ref($customer)) {
673720
$customer = $customer->id;
@@ -1595,6 +1642,10 @@ sub convert_to_form_fields {
15951642
foreach my $fn (keys %fields) {
15961643
$r->{$fn} = $fields{$fn};
15971644
}
1645+
} elsif ($key eq 'metadata' && ref($hash->{$key}) eq 'HASH') {
1646+
foreach my $fn (keys %{$hash->{$key}}) {
1647+
$r->{$key . '[' . $fn . ']'} = $hash->{$key}->{$fn};
1648+
}
15981649
} else {
15991650
$r->{$key} = $hash->{$key};
16001651
}

lib/Net/Stripe/Card.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ has 'address_zip' => (is => 'ro', isa => 'Maybe[Str]');
1616
has 'address_city' => (is => 'ro', isa => 'Maybe[Str]');
1717
has 'address_state' => (is => 'ro', isa => 'Maybe[Str]');
1818
has 'address_country' => (is => 'ro', isa => 'Maybe[Str]');
19-
has 'metadata' => (is => 'rw', isa => 'Maybe[HashRef]');
19+
has 'metadata' => (is => 'ro', isa => 'Maybe[HashRef]');
2020

2121
# Both input and output
2222
has 'exp_month' => (is => 'ro', isa => 'Maybe[Int]', required => 1);

t/live.t

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,66 @@ Customers: {
680680

681681
}
682682

683+
Update_existing_card_for_customer_id: {
684+
my $token = $stripe->post_token(card => $fake_card);
685+
my $customer = $stripe->post_customer(
686+
card => $token->id,
687+
);
688+
isa_ok $customer, 'Net::Stripe::Customer', 'got back a customer';
689+
my $cards = $stripe->get_cards(
690+
customer => $customer->id,
691+
);
692+
isa_ok $cards, 'Net::Stripe::List', 'Card List object returned';
693+
is scalar @{$cards->data}, 1, 'customer only has one card';
694+
695+
my $card = @{$cards->data}[0];
696+
isa_ok $card, 'Net::Stripe::Card';
697+
698+
is $card->id, $token->card->id, 'card token id matches';
699+
700+
for my $f (sort grep { $_ ne 'cvc' && $_ ne 'number' && $_ ne 'metadata' } keys %{$fake_card}) {
701+
is $card->$f, $fake_card->{$f}, "card $f matches";
702+
}
703+
my $card_id = $card->id;
704+
705+
my $future_future = $future + DateTime::Duration->new(years => 1);
706+
my $updated_fake_card = {
707+
name => 'Dr. Anonymous',
708+
address_line1 => '321 Easy Street',
709+
address_city => 'Beverly Hills',
710+
address_state => 'California',
711+
address_zip => '90210',
712+
address_country => 'United States',
713+
exp_month => $future_future->month,
714+
exp_year => $future_future->year,
715+
metadata => {
716+
'somenewcardmetadata' => 'can you hear me now?',
717+
},
718+
};
719+
720+
$stripe->update_card(
721+
customer_id => $customer->id,
722+
card_id => $card->id,
723+
card => $updated_fake_card,
724+
);
725+
726+
$cards = $stripe->get_cards(
727+
customer => $customer->id,
728+
);
729+
isa_ok $cards, 'Net::Stripe::List', 'Card List object returned';
730+
is scalar @{$cards->data}, 1, 'customer still only has one card';
731+
732+
$card = @{$cards->data}[0];
733+
is $card->id, $card_id, "card id still matches";
734+
735+
for my $f (sort grep { $_ ne 'metadata' } keys %{$updated_fake_card}) {
736+
is $card->$f, $updated_fake_card->{$f}, "updated card $f matches";
737+
}
738+
for my $k (sort keys %{$updated_fake_card->{metadata}}) {
739+
is $card->metadata->{$k}, $updated_fake_card->{metadata}->{$k}, "updated card metadata $k matches";
740+
}
741+
}
742+
683743
Customers_with_plans: {
684744
my $freeplan = $stripe->post_plan(
685745
id => "free-$future_ymdhms",

0 commit comments

Comments
 (0)