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 407 ahitrov '20' => 'Wrong order identity',
41 358 ahitrov '30' => 'Temporary error',
42 '40' => 'Fatal error',
43 );
44 405 ahitrov my @valid_subnets = grep { index($_, '/') > 0 } @valid_ips;
45 my $subnet_matcher;
46 if ( @valid_subnets ) {
47 $subnet_matcher = subnet_matcher @valid_subnets;
48 @valid_ips = grep { index($_, '/') == -1 } @valid_ips;
49 }
50 358 ahitrov
51 </%once>
52 <%args>
53
54 $id => undef
55 $v1 => ''
56 $v2 => ''
57 $v3 => ''
58 $amount => undef
59 $currency => undef
60 $datetime => undef
61 $test => undef
62 $sign => undef
63 $user_sum => undef
64 $user_currency => undef
65 $transfer_sum => undef
66 $transfer_currency => undef
67 $pid => undef
68 $id_geotype => undef
69
70 </%args>
71 <%init>
72
73 404 ahitrov my $DEBUG = 1;
74 358 ahitrov warn Dumper \%ARGS if $DEBUG;
75
76 359 ahitrov my $str = $v1.$amount.$currency.$id.$state->{payments}{xsolla_app_secret};
77 358 ahitrov my $md5 = Digest::MD5::md5_hex ( $str );
78 warn "MD5 Check: $md5\n" if $DEBUG;
79
80 my $code = 0;
81 my $ip = $r->header_in('X-Real-IP');
82 369 ahitrov warn "From IP=$ip\n" if $DEBUG;
83 358 ahitrov my $transaction;
84 405 ahitrov my $security_check = $md5 eq $sign ? 1 : 0;
85 if ( $security_check ) {
86 if ( grep { $ip eq $_ } @valid_ips ) {
87 } elsif ( @valid_subnets ) {
88 $security_check = $subnet_matcher->($ip);
89 warn "IP [$ip] didn't match any of ".Dumper(\@valid_subnets)." subnets nor ".Dumper(\@valid_ips)." single IPs\n";
90 } else {
91 $security_check = 0;
92 warn "IP [$ip] didn't match any of ".Dumper(\@valid_ips)." single IPs\n";
93 }
94 }
95 if ( $security_check ) {
96 358 ahitrov my $last = $keeper->{payments}->check( $v1 );
97 407 ahitrov if ( $last ) {
98 if ( $last->name eq 'cancel' || $last->name eq 'suspend') {
99 $code = 20;
100 }
101 unless ( $code ) {
102 ($transaction) = $keeper->get_documents(
103 class => 'payments::Transaction',
104 order_id => $v1,
105 operation_id => $id,
106 provider => 'xsolla',
107 limit => 1,
108 );
109 if ( ref $transaction ) {
110 $code = 0;
111 } else {
112 my $dt = $datetime =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/ ? "$1-$2-$3 $4:$5:$6" : '';
113 $transaction = payments::Transaction->new( $keeper );
114 $transaction->status( $test || 0 );
115 $transaction->provider( 'xsolla' );
116 $transaction->order_id( $v1 );
117 $transaction->operation_id( $id );
118 $transaction->sum( $amount );
119 $transaction->currency_code( $currency );
120 $transaction->dtime( $dt ) if $dt;
121 $transaction->custom1( $v2 );
122 $transaction->custom2( $v3 );
123 $transaction->name( $v2 || $v3 );
124 $transaction->store();
125 362 ahitrov
126 407 ahitrov if ( $keeper->can('_xsolla_handler') ) {
127 unless ( $keeper->_xsolla_handler( $transaction ) ) {
128 $code = 30;
129 }
130 362 ahitrov }
131 }
132 358 ahitrov }
133 407 ahitrov } else {
134 $code = 20;
135 358 ahitrov }
136 } else {
137 404 ahitrov warn "Wrong transaction parameters: IP=$ip. Available ip list [".Dumper(\@valid_ips)."]. String: $str. MD5: $md5. Sign: $sign\n";
138 407 ahitrov $code = 40;
139 358 ahitrov }
140
141 </%init>