EV-Telegram-TDLib

 view release on metacpan or  search on metacpan

lib/EV/Telegram/TDLib/Payments.pm  view on Meta::CPAN

package EV::Telegram::TDLib::Payments;

use strict;
use warnings;
use Carp qw(croak);
use MIME::Base64 ();

our $VERSION = '0.04';

=head1 NAME

EV::Telegram::TDLib::Payments - payment methods for EV::Telegram::TDLib

=head1 DESCRIPTION

One of the mixins L<EV::Telegram::TDLib> inherits from. It has no
interface of its own and is not meant to be used directly: loading the
main module loads this one, and its methods are called on a client.

They are documented together with the rest of the API, under
L<EV::Telegram::TDLib/"Payments mixin">.

=cut

sub CLONE_SKIP { 1 }


our %UPDATES = (
    updateNewPreCheckoutQuery => \&update_pre_checkout,
    updateNewShippingQuery    => \&update_shipping,
);

# The invoice payload is the seller's own order id, handed back at checkout.
# It is TL bytes in inputMessageInvoice and in updateNewPreCheckoutQuery, but a
# plain string in updateNewShippingQuery -- encoding all three alike corrupts
# the shipping one, so each is handled on its own terms.
sub update_pre_checkout {
    my ($self, $obj) = @_;
    my $cb = $self->{on_pre_checkout_query} or return;
    $cb->({
        id              => $obj->{id},
        sender_user_id  => $obj->{sender_user_id},
        currency        => $obj->{currency},
        total_amount    => $obj->{total_amount},
        payload         => MIME::Base64::decode_base64($obj->{invoice_payload} // ''),
        shipping_option_id => $obj->{shipping_option_id},
        order_info      => $obj->{order_info},
    });
}

sub update_shipping {
    my ($self, $obj) = @_;
    my $cb = $self->{on_shipping_query} or return;
    $cb->({
        id                => $obj->{id},
        sender_user_id    => $obj->{sender_user_id},
        payload           => $obj->{invoice_payload},
        shipping_address  => $obj->{shipping_address},
    });
}

sub on_pre_checkout_query {
    my ($self, $cb) = @_;
    $self->{on_pre_checkout_query} = $cb if @_ > 1;
    return $self->{on_pre_checkout_query};
}

sub on_shipping_query {
    my ($self, $cb) = @_;
    $self->{on_shipping_query} = $cb if @_ > 1;
    return $self->{on_shipping_query};
}

sub price_parts {
    my ($prices) = @_;
    croak 'prices must be an arrayref' unless ref $prices eq 'ARRAY';
    croak 'an invoice needs at least one price' unless @$prices;
    return [ map {
        my ($label, $amount) = ref $_ eq 'ARRAY'  ? @$_
                             : ref $_ eq 'HASH'   ? @{$_}{qw(label amount)}
                             : croak 'each price must be an arrayref or hashref';
        croak 'each price needs a label and an amount'
            unless defined $label && defined $amount;
        { '@type' => 'labeledPricePart', label => plain_text('a price label', $label),
          amount => num('price amount', $amount) };
    } @$prices ];
}

# Amounts are in the currency's smallest unit -- cents, not euros -- except for
# XTR, where one unit is one Star. Selling digital goods for Stars needs no
# payment provider at all, so provider_token stays empty.
sub invoice_content {
    my ($spec) = @_;
    croak 'send_invoice needs a hashref describing the invoice'
        unless ref $spec eq 'HASH';
    need('title, description, payload, currency, prices',
          @{$spec}{qw(title description payload currency prices)});
    return {
        '@type'      => 'inputMessageInvoice',
        invoice      => {
            '@type'                => 'invoice',
            currency               => plain_text('a currency', $spec->{currency}),
            price_parts            => price_parts($spec->{prices}),
            max_tip_amount         => num('max_tip', $spec->{max_tip} // 0),
            suggested_tip_amounts  => num_list('tips', $spec->{tips} // []),
            is_test                => json_bool($spec->{test}),
            need_name              => json_bool($spec->{need_name}),
            need_phone_number      => json_bool($spec->{need_phone}),
            need_email_address     => json_bool($spec->{need_email}),
            need_shipping_address  => json_bool($spec->{need_shipping}),
            send_phone_number_to_provider => json_bool($spec->{send_phone_to_provider}),



( run in 0.405 second using v1.01-cache-2.11-cpan-57ff5998125 )