MyRedland/lib/MyRedland/Stripe.pm

183 lines
4.4 KiB
Perl

package MyRedland::Stripe;
use v5.34.1;
use strict;
use warnings;
use MyRedland::DB;
use MyRedland::Lusers;
use Mojo::UserAgent;
use Moo;
use Params::ValidationCompiler qw/validation_for/;
use Types::Standard qw/Str InstanceOf HashRef Int Bool/;
use MIME::Base64;
use Data::Dumper;
use Mojo::Util qw/url_escape/;
my $ua = Mojo::UserAgent->new;
has app => (
is => 'ro',
isa => InstanceOf ['Mojolicious'],
);
has _dbh => ( is => 'lazy', );
has _stripe_secret => ( is => 'lazy', );
has _users_dao => ( is => 'lazy', );
sub _build__dbh {
my $self = shift;
return MyRedland::DB->new( app => $self->app );
}
sub _build__stripe_secret {
my $self = shift;
return $self->app->config->{stripe_secret};
}
sub _build__users_dao {
my $self = shift;
return MyRedland::Lusers->new( app => $self->app );
}
{
my $validator = validation_for(
params => {
method => { type => Str },
url => { type => Str },
form => { type => HashRef, optional => 1 },
headers => { type => HashRef, optional => 1 },
}
);
sub _make_request {
my $self = shift;
my %params = $validator->(@_);
my $method = $params{method};
my $url = $params{url};
my $headers = $params{headers} // {};
$headers->{Authorization} =
'Basic ' . encode_base64( $self->_stripe_secret . ':', '' );
my $form = $params{form};
my $tx = $ua->build_tx( $method, $url, $headers,
( ( defined $form ) ? ( form => $form ) : () ) );
return $ua->start($tx);
}
}
sub create_customer_for_user {
my $self = shift;
my $user = shift;
if ( defined $user->stripe_customer_id ) {
return $user;
}
my $response = $self->_make_request(
method => 'POST',
url => 'https://api.stripe.com/v1/customers'
)->result->json;
$user->stripe_customer_id( $response->{id} );
$user = $self->_users_dao->update(
user => $user,
fields => [qw/stripe_customer_id/]
);
return $user;
}
{
my $validator = validation_for(
params => {
user => {
type => InstanceOf ['MyRedland::Luser'],
},
price => {
type => Int,
},
off_session => {
type => Bool
},
}
);
sub create_payment_intent {
my $self = shift;
my %params = $validator->(@_);
my ( $user, $price, $off_session ) =
@params{qw/user price off_session/};
my $response = $self->_make_request(
method => 'POST',
url => 'https://api.stripe.com/v1/payment_intents',
form => {
currency => 'eur',
amount => $price,
'payment_method_types[]' => 'card',
customer => $user->stripe_customer_id,
( ($off_session) ? ( off_session => $off_session ) : () ),
}
)->result->json;
if ( defined $response->{error} ) {
die Data::Dumper::Dumper $response->{error};
}
return $response;
}
}
{
my $validator = validation_for(
params => {
payment_intent_id => {
type => Str
}
}
);
sub retrieve_payment_intent {
my $self = shift;
my %params = $validator->(@_);
my ($payment_intent_id) = $params{'payment_intent_id'};
my $response = $self->_make_request(
method => 'GET',
url => 'https://api.stripe.com/v1/payment_intents/'.url_escape($payment_intent_id),
)->result->json;
if ( defined $response->{error} ) {
die Data::Dumper::Dumper $response->{error};
}
return $response;
}
}
{
my $validator = validation_for(
params => {
payment_intent_id => {
type => Str
},
updates => {
type => HashRef
}
}
);
sub update_payment_intent {
my $self = shift;
my %params = $validator->(@_);
my ($payment_intent_id, $updates) = @params{qw/payment_intent_id updates/};
my $response = $self->_make_request(
method => 'POST',
url => 'https://api.stripe.com/v1/payment_intents/'.url_escape($payment_intent_id),
form => $updates,
)->result->json;
print Data::Dumper::Dumper $response;
if ( defined $response->{error} ) {
die Data::Dumper::Dumper $response->{error};
}
return $response;
}
}
1;