Line # Revision Author
1 358 ahitrov <?xml version="1.0" encoding="UTF-8"?>
2 <response>
3 <result><% $code %></result>
4 <description><% $codes{$code} %></description>
5 <fields>
6 <id><% $id %></id>
7 <order><% $v1 %></order>
8 <amount><% $amount %></amount>
9 <currency><% $currency %></currency>
10 <datetime><% $datetime %></datetime>
11 <sign><% $sign %></sign>
12 </fields>
13 </response>
14 <%doc>
15
16 сommand Признак того, что идет оповещение о платеже
17 id Уникальный id операции в системе «Иксолла»
18 v1 Уникальный идентификатор заказа, полученный от проекта. В XML-ответе значение этого параметра следует передававть в параметре order.
19 amount Стоимость заказа. Разделитель “.” (2 знака после точки)
20 currency Валюта заказа. Используется трехбуквенное обозначение валюты согласно стандарту ISO 4217
21 datetime Дата в формате ГГГГММДДЧЧММСС
22 test Признак тестовой транзакции. test=1 – система проводит тестовую транзакцию. Реального платежа не было. test=0 – реальный платеж
23 sign Подпись для предотвращения несанкционированного доступа
24 user_sum Размер платежа, совершенного пользователем. Разделитель “.” (2 знака после точки)
25 user_currency Валюта платежа, совершенного пользователем. Используется трехбуквенное обозначение валюты согласно стандарту ISO 4217
26 transfer_sum Сумма выплаты проекту. Разделитель “.” (2 знака после точки)
27 transfer_currency Валюта выплаты проекту. Используется трехбуквенное обозначение валюты согласно стандарту ISO 4217
28 pid Идентификационный номер платежной системы
29 id_geotype id валюты платежной системы
30
31 </%doc>
32 <%once>
33
34 use Digest::MD5;
35 405 ahitrov use Net::Subnet;
36
37 369 ahitrov my @valid_ips = @{$state->{payments}{xsolla_valid_ips}};
38 358 ahitrov my %codes = (
39 '0' => 'Success',
40 '10' => 'Another delivery attempt',
41 '20' => 'Wrong parameters',
42 '30' => 'Temporary error',
43 '40' => 'Fatal error',
44 );
45 405 ahitrov my @valid_subnets = grep { index($_, '/') > 0 } @valid_ips;
46 my $subnet_matcher;
47 if ( @valid_subnets ) {
48 $subnet_matcher = subnet_matcher @valid_subnets;
49 @valid_ips = grep { index($_, '/') == -1 } @valid_ips;
50 }
51 358 ahitrov
52 </%once>
53 <%args>
54
55 $id => undef
56 $v1 => ''
57 $v2 => ''
58 $v3 => ''
59 $amount => undef
60 $currency => undef
61 $datetime => undef
62 $test => undef
63 $sign => undef
64 $user_sum => undef
65 $user_currency => undef
66 $transfer_sum => undef
67 $transfer_currency => undef
68 $pid => undef
69 $id_geotype => undef
70
71 </%args>
72 <%init>
73
74 404 ahitrov my $DEBUG = 1;
75 358 ahitrov warn Dumper \%ARGS if $DEBUG;
76
77 359 ahitrov my $str = $v1.$amount.$currency.$id.$state->{payments}{xsolla_app_secret};
78 358 ahitrov my $md5 = Digest::MD5::md5_hex ( $str );
79 warn "MD5 Check: $md5\n" if $DEBUG;
80
81 my $code = 0;
82 my $ip = $r->header_in('X-Real-IP');
83 369 ahitrov warn "From IP=$ip\n" if $DEBUG;
84 358 ahitrov my $transaction;
85 405 ahitrov my $security_check = $md5 eq $sign ? 1 : 0;
86 if ( $security_check ) {
87 if ( grep { $ip eq $_ } @valid_ips ) {
88 } elsif ( @valid_subnets ) {
89 $security_check = $subnet_matcher->($ip);
90 warn "IP [$ip] didn't match any of ".Dumper(\@valid_subnets)." subnets nor ".Dumper(\@valid_ips)." single IPs\n";
91 } else {
92 $security_check = 0;
93 warn "IP [$ip] didn't match any of ".Dumper(\@valid_ips)." single IPs\n";
94 }
95 }
96 if ( $security_check ) {
97 358 ahitrov my $last = $keeper->{payments}->check( $v1 );
98 if ( $last->name eq 'cancel' ) {
99 $code = 40;
100 } elsif ( $last->name eq 'suspend' ) {
101 $code = 20;
102 }
103 unless ( $code ) {
104 ($transaction) = $keeper->get_documents(
105 class => 'payments::Transaction',
106 order_id => $v1,
107 operation_id => $id,
108 provider => 'xsolla',
109 limit => 1,
110 );
111 if ( ref $transaction ) {
112 $code = 10;
113 } else {
114 my $dt = $datetime =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/ ? "$1-$2-$3 $4:$5:$6" : '';
115 $transaction = payments::Transaction->new( $keeper );
116 $transaction->status( $test || 0 );
117 $transaction->provider( 'xsolla' );
118 $transaction->order_id( $v1 );
119 $transaction->operation_id( $id );
120 $transaction->sum( $amount );
121 $transaction->currency_code( $currency );
122 $transaction->dtime( $dt ) if $dt;
123 $transaction->custom1( $v2 );
124 $transaction->custom2( $v3 );
125 $transaction->name( $v2 || $v3 );
126 $transaction->store();
127 362 ahitrov
128 if ( $keeper->can('_xsolla_handler') ) {
129 unless ( $keeper->_xsolla_handler( $transaction ) ) {
130 $code = 30;
131 }
132 }
133 358 ahitrov }
134 }
135 } else {
136 404 ahitrov warn "Wrong transaction parameters: IP=$ip. Available ip list [".Dumper(\@valid_ips)."]. String: $str. MD5: $md5. Sign: $sign\n";
137 358 ahitrov $code = 20;
138 }
139
140 </%init>