Revision 407 (by ahitrov, 2014/01/22 14:28:44) Xsolla return codes matches last documented values

<?xml version="1.0" encoding="UTF-8"?>
<response>
	<result><% $code %></result>
	<description><% $codes{$code} %></description> 
	<fields>
		<id><% $id %></id>
		<order><% $v1 %></order>
		<amount><% $amount %></amount> 
		<currency><% $currency %></currency> 
		<datetime><% $datetime %></datetime> 
		<sign><% $sign %></sign>
	</fields> 
</response>
<%doc>

   сommand	Признак того, что идет оповещение о платеже
   id		Уникальный id операции в системе «Иксолла»
   v1		Уникальный идентификатор заказа, полученный от проекта. В XML-ответе значение этого параметра следует передававть в параметре order.
   amount	Стоимость заказа. Разделитель “.” (2 знака после точки)
   currency	Валюта заказа. Используется трехбуквенное обозначение валюты согласно стандарту ISO 4217
   datetime	Дата в формате ГГГГММДДЧЧММСС
   test		Признак тестовой транзакции. test=1 – система проводит тестовую транзакцию. Реального платежа не было. test=0 – реальный платеж
   sign		Подпись для предотвращения несанкционированного доступа
   user_sum	Размер платежа, совершенного пользователем. Разделитель “.” (2 знака после точки)
   user_currency	Валюта платежа, совершенного пользователем. Используется трехбуквенное обозначение валюты согласно стандарту ISO 4217
   transfer_sum		Сумма выплаты проекту. Разделитель “.” (2 знака после точки)
   transfer_currency	Валюта выплаты проекту. Используется трехбуквенное обозначение валюты согласно стандарту ISO 4217
   pid		Идентификационный номер платежной системы
   id_geotype	id валюты платежной системы

</%doc>
<%once>

    use Digest::MD5;
    use Net::Subnet;

    my @valid_ips = @{$state->{payments}{xsolla_valid_ips}};
    my %codes = (
	'0'	=> 'Success',
	'20'	=> 'Wrong order identity',
	'30'	=> 'Temporary error',
	'40'	=> 'Fatal error',
    );
    my @valid_subnets = grep { index($_, '/') > 0 } @valid_ips;
    my $subnet_matcher;
    if ( @valid_subnets ) {
	$subnet_matcher = subnet_matcher @valid_subnets;
	@valid_ips = grep { index($_, '/') == -1 } @valid_ips;
    }

</%once>
<%args>

	$id		=> undef
	$v1		=> ''
	$v2		=> ''
	$v3		=> ''
	$amount		=> undef
	$currency	=> undef
	$datetime	=> undef
	$test		=> undef
	$sign		=> undef
	$user_sum	=> undef
	$user_currency	=> undef
	$transfer_sum	=> undef
	$transfer_currency	=> undef
	$pid		=> undef
	$id_geotype	=> undef

</%args>
<%init>

    my $DEBUG = 1;
    warn Dumper \%ARGS				if $DEBUG;

    my $str = $v1.$amount.$currency.$id.$state->{payments}{xsolla_app_secret};
    my $md5 = Digest::MD5::md5_hex ( $str );
    warn "MD5 Check: $md5\n"			if $DEBUG;

    my $code = 0;
    my $ip = $r->header_in('X-Real-IP');
    warn "From IP=$ip\n"			if $DEBUG;
    my $transaction;
    my $security_check = $md5 eq $sign ? 1 : 0;
    if ( $security_check ) {
	if ( grep { $ip eq $_ } @valid_ips ) {
	} elsif ( @valid_subnets ) {
		$security_check  = $subnet_matcher->($ip);
		warn "IP [$ip] didn't match any of ".Dumper(\@valid_subnets)." subnets nor ".Dumper(\@valid_ips)." single IPs\n";
	} else {
		$security_check = 0;
		warn "IP [$ip] didn't match any of ".Dumper(\@valid_ips)." single IPs\n";
	}
    }
    if ( $security_check ) {
	my $last = $keeper->{payments}->check( $v1 );
	if ( $last ) {
		if ( $last->name eq 'cancel' || $last->name eq 'suspend') {
			$code = 20;
		}
		unless ( $code ) {
			($transaction) = $keeper->get_documents(
						class	=> 'payments::Transaction',
						order_id	=> $v1,
						operation_id	=> $id,
						provider	=> 'xsolla',
						limit	=> 1,
				);
			if ( ref $transaction ) {
				$code = 0;
			} else {
				my $dt = $datetime =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/ ? "$1-$2-$3 $4:$5:$6" : '';
				$transaction = payments::Transaction->new( $keeper );
				$transaction->status( $test || 0 );
				$transaction->provider( 'xsolla' );
				$transaction->order_id( $v1 );
				$transaction->operation_id( $id );
				$transaction->sum( $amount );
				$transaction->currency_code( $currency );
				$transaction->dtime( $dt )	if $dt;
				$transaction->custom1( $v2 );
				$transaction->custom2( $v3 );
				$transaction->name( $v2 || $v3 );
				$transaction->store();

				if ( $keeper->can('_xsolla_handler') ) {
					unless ( $keeper->_xsolla_handler( $transaction ) ) {
						$code = 30;
					}
				}
			}
		}
	} else {
		$code = 20;
	}
    } else {
	warn "Wrong transaction parameters: IP=$ip. Available ip list [".Dumper(\@valid_ips)."]. String: $str. MD5: $md5. Sign: $sign\n";
	$code = 40;
    }

</%init>