Покупка в ВК в IFrame-приложениях

В этой статье я расскажу, как сделать оплату в Ваших IFrame-приложениях в ВКонтакте.
Все предельно просто, нужно сделать какую-нибудь внутреннюю валюту для Вашего приложения и продавать ее за голоса. Я назвал свою валюту просто — «монетки». Когда определились с своей валютой, нужно реализовать ее покупку. Для удобства разработки ВК сделали два режима оплаты: тестовая и «боевая». Тестовый режим доступен сразу после создания приложения, а рабочий, только после прохождения модерации.
Начнем писать код. В первую очередь нужно написать callback.php — этот скрипт указывается в приложении(во вкладке «Платежи») для обратного вызова. Callback.php — будет обрабатывать запросы от ВК, и отдавать информацию о нашем товаре(монетках) и обрабатывать статус заказа. В приведенном ниже коде все понятно, где нужно я написал комментарии. В коде я обращался к базе данных через модели, но Вы можете переписать под себя.

<?php 
 header("Content-Type: application/json; encoding=utf-8"); 
 $secret_key = 'TPZbwTcE5I**********'; // Защищенный ключ приложения 
 $input = $_POST; 
 // Проверка подписи 
 $sig = $input['sig']; 
 unset($input['sig']); 
 ksort($input); 
 $str = ''; 
 foreach ($input as $k => $v) { 
   $str .= $k.'='.$v; 
 } 
 if ($sig != md5($str.$secret_key)) { 
   $response['error'] = array( 
     'error_code' => 10, 
     'error_msg' => 'Несовпадение вычисленной и переданной подписи запроса.', 
     'critical' => true 
   ); 
 } else { 
   // Подпись правильная 
   switch ($input['notification_type']) {
	case 'get_item': 
	   // Получение информации о товаре
	   $item = $input['item']; 
	   if ($item == 'item1') { 
		 $response['response'] = array( 
		   'item_id' => 3,
		   'title' => '3 монетки', 
		   'photo_url' => 'http://bestmems.vk-book.ru/img/maney_coin.png', 
		   'price' => 3 
		 ); 
	   } elseif ($item == 'item2') { 
		 $response['response'] = array( 
		   'item_id' => 5, 
		   'title' => '5 монеток', 
		   'photo_url' => 'http://bestmems.vk-book.ru/img/maney_coin.png', 
		   'price' => 5 
		 ); 
	   } 
	   break; 
	case 'get_item_test': 
       // Получение информации о товаре в тестовом режиме 
       $item = $input['item']; 
       if ($item == 'item1') { 
         $response['response'] = array( 
           'item_id' => 3, 
           'title' => '3 монетки (тестовый режим)', 
           'photo_url' => 'http://bestmems.vk-book.ru/img/maney_coin.png', 
           'price' => 3 
         ); 
       } elseif ($item == 'item2') { 
         $response['response'] = array( 
           'item_id' => 5, 
           'title' => '5 монеток (тестовый режим)', 
           'photo_url' => 'http://bestmems.vk-book.ru/img/maney_coin.png', 
           'price' => 5 
         ); 
       }
       break; 
 case 'order_status_change': 
       // Изменение статуса заказа в тестовом режиме 
	if ($input['status'] == 'chargeable') { 
		$order_id = intval($input['order_id']); 
		$user_id  = intval($input['user_id']);
		$item_id_c  = intval($input['item_id']);
		
		require_once '../classes/Bootstrap.php';
		$date_time = date('Y-m-d') . ' ' . date('H:i:s');
		// проверяем, может такой заказ уже есть
		$select = OrdersPeer::getInstance()->select()->setIntegrityCheck(false)
			->where(OrdersPeer::ORDER_ID . ' = 1234')
			->limit(1);
		$selectRow = MemsPeer::getInstance()->fetchRow($select);
		if(count($selectRow)>0){
			// если есть такой заказ, то ни чего не делаем
		}elseif(count($selectRow)==0){
			// если такго заказа нет, то записываем его в бд и увеличиваем счет пользователя
			$db = Db::getConnection ();
			$sql = "
			   INSERT INTO `orders` (`vk_uid`, `order_id`, `item_id`, `date`) VALUES ({$user_id}, {$order_id}, {$item_id_c}, '{$date_time}');
			   UPDATE `autors` SET `money`=`money`+{$item_id_c} WHERE `autors`.`id_vk`='{$user_id}';
			";
			$result = $db->query($sql);
		}
		$app_order_id = 1; // Тут фактического заказа может не быть - тестовый режим. 

		$response['response'] = array( 
           'order_id' => $order_id, 
           'app_order_id' => $app_order_id, 
        ); 
       } else { 
         $response['error'] = array( 
           'error_code' => 100, 
           'error_msg' => 'Передано непонятно что вместо chargeable.', 
           'critical' => true 
         ); 
       } 
       break; 

 case 'order_status_change_test': 
       // Изменение статуса заказа в тестовом режиме 
	if ($input['status'] == 'chargeable') { 
		$order_id = intval($input['order_id']); 
		$user_id  = intval($input['user_id']);
		$item_id_c  = intval($input['item_id']);
		
		require_once '../classes/Bootstrap.php';
		$date_time = date('Y-m-d') . ' ' . date('H:i:s');
		// проверяем, может такой заказ уже есть !!! Это обязательно, поскольку ВК может послать один запрос несколько раз
		$select = OrdersPeer::getInstance()->select()->setIntegrityCheck(false)
			->where(OrdersPeer::ORDER_ID . ' = 1234')
			->limit(1);
		$selectRow = MemsPeer::getInstance()->fetchRow($select);
		if(count($selectRow)>0){
			// если есть такой заказ, то ни чего не делаем
		}elseif(count($selectRow)==0){
			// если такго заказа нет, то записываем его в бд и увеличиваем счет пользователя
			$db = Db::getConnection ();
			$sql = "
			   INSERT INTO `orders` (`vk_uid`, `order_id`, `item_id`, `date`) VALUES ({$user_id}, {$order_id}, {$item_id_c}, '{$date_time}');
			   UPDATE `autors` SET `money`=`money`+{$item_id_c} WHERE `autors`.`id_vk`='{$user_id}';
			";
			$result = $db->query($sql);
		}
		$app_order_id = 1; // Тут фактического заказа может не быть - тестовый режим. 

		$response['response'] = array( 
           'order_id' => $order_id, 
           'app_order_id' => $app_order_id, 
        ); 
       } else { 
         $response['error'] = array( 
           'error_code' => 100, 
           'error_msg' => 'Передано непонятно что вместо chargeable.', 
           'critical' => true 
         ); 
       } 
       break; 
   } 
 } 

 echo json_encode($response); 
 ?>

Теперь сделаем кнопки для вызова оплаты и напишем js, который будет обрабатывать статусы выполнения оплаты:

<input type="button" value ="Купить 3 монетки" id="item1"/>
<input type="button" value ="Купить 5 монеток" id="item2"/>
<script type="text/javascript">
$(document).ready(function(){
	$('#item1').click(function(){
		order('item1');
	});
	$('#item2').click(function(){
		order('item2');
	});
});
  function order(item_num) {
    var params = {
      type: 'item',
      item: item_num
    };
    VK.callMethod('showOrderBox', params);
  }

  VK.addCallback('onOrderSuccess', function(order_id) {
   // оплата прошла успешно, order_id - id заказа
     alert("Оплата прошла успешно. ID заказа: " + order_id);
   // тут можно сделать, ajax запрос, который вытащит из бд обновленное количество монеток.
  });
  
  VK.addCallback('onOrderFail', function() {
    alert('Ошибка оплаты, попробуйте повторить позже');
  });
  VK.addCallback('onOrderCancel', function() {
    alert('Оплата отменена пользователем');
  });
</script>

Вот и все. Оказывается сделать оплату в приложениях очень просто!

Рассказать друзьям:


Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*