Skip to content

Commit 72a6b24

Browse files
committed
Purchase api updates
1 parent 385fa8e commit 72a6b24

File tree

6 files changed

+108
-23
lines changed

6 files changed

+108
-23
lines changed

app/Http/Controllers/Api/PurchaseController.php

+82-10
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Phonex\Jobs\IssueProductLicense;
1111
use Phonex\Model\OrderInapp;
1212
use Phonex\Model\OrderInappState;
13+
use Phonex\Model\OrderPlayInapp;
1314
use Phonex\Model\Product;
1415
use Phonex\Purchase\PlayPurchase;
1516
use Phonex\User;
@@ -27,9 +28,10 @@ class PurchaseController extends Controller {
2728
const RESULT_ERR_INVALID_PRODUCT = 4;
2829
const RESULT_ERR_TEST = 5;
2930
const RESULT_ERR_INVALID_SIGNATURE = 6;
31+
const RESULT_ERR_EXISTING_ORDER_ID = 7;
32+
const RESULT_MULTIPLE_PURCHASES = 8; // when saving multiple purchases
3033

31-
32-
/*These codes are coming from apple itunes store*/
34+
/* These codes are coming from apple itunes store */
3335
// The App Store could not read the JSON object you provided.
3436
const RESULT_APPSTORE_CANNOT_READ = 21000;
3537
// The data in the receipt-data property was malformed or missing.
@@ -54,6 +56,11 @@ class PurchaseController extends Controller {
5456
public function __construct(){
5557
}
5658

59+
/**
60+
* Main processing method for Google Play store transactions
61+
* @param Request $request
62+
* @return string
63+
*/
5764
public function postAndroidPaymentVerification(Request $request)
5865
{
5966
$user = $request->attributes->get(MiddlewareAttributes::CLIENT_CERT_AUTH_USER);
@@ -63,31 +70,79 @@ public function postAndroidPaymentVerification(Request $request)
6370

6471
// Parse json
6572
$jsonReq = $request->get('request');
66-
$playPurchase = PlayPurchase::fromJson($jsonReq);
73+
$jsonObject = json_decode($jsonReq, true);
74+
$playPurchase = PlayPurchase::fromJsonObject($jsonObject);
75+
76+
// Process Ticket
77+
$returnCode = $this->processPlayPurchase($playPurchase, $user);
78+
if ($returnCode == self::RESULT_OK){
79+
Log::info("received google payment verification", [$returnCode, $jsonReq]);
80+
} else {
81+
Log::error("received google payment verification", [$returnCode, $jsonReq]);
82+
}
6783

68-
if ($playPurchase === null){
69-
Log::error("json_decode failed", [$jsonReq]);
84+
return $this->getResponse($returnCode);
85+
}
86+
87+
/**
88+
* Processes array of payments
89+
* @param Request $request
90+
* @return string
91+
*/
92+
public function postAndroidPaymentsVerification(Request $request)
93+
{
94+
$user = $request->attributes->get(MiddlewareAttributes::CLIENT_CERT_AUTH_USER);
95+
if (!$user){
96+
return $this->getResponse(self::RESULT_ERR_INVALID_USER);
97+
}
98+
99+
100+
$jsonReq = $request->get('request');
101+
$jsonObjects = json_decode($jsonReq, true);
102+
if ($jsonObjects == null || !is_array($jsonObjects)){
70103
return $this->getResponse(self::RESULT_ERR_JSON_PARSING);
71104
}
105+
106+
$responseArray = [];
107+
// Process purchases one by one
108+
foreach($jsonObjects as $jsonObject){
109+
$playPurchase = PlayPurchase::fromJsonObject($jsonObject);
110+
$errCode = $this->processPlayPurchase($playPurchase, $user);
111+
$responseArray[] = $errCode;
112+
}
113+
Log::info("received google payment verifications", [$responseArray, $jsonReq]);
114+
return $this->getResponseForMultiplePurchases($responseArray);
115+
}
116+
117+
118+
private function processPlayPurchase(PlayPurchase $playPurchase, User $user)
119+
{
120+
if ($playPurchase === null){
121+
return self::RESULT_ERR_JSON_PARSING;
122+
}
72123
if (!$playPurchase->verifySignature()){
73-
return $this->getResponse(self::RESULT_ERR_INVALID_SIGNATURE);
124+
return self::RESULT_ERR_INVALID_SIGNATURE;
125+
}
126+
// order id should be unique, otherwise the transaction is replayed
127+
if (OrderPlayInapp::orderIdExists($playPurchase->orderId, $user)){
128+
return self::RESULT_ERR_EXISTING_ORDER_ID;
74129
}
75130

76131
// First save the order
77132
$orderPlayInapp = $playPurchase->createDatabaseModel($user);
78133
$orderPlayInapp->save();
79134

80-
Log::info("received google payment verification", [$jsonReq, $playPurchase, $orderPlayInapp]);
135+
Log::info("received google payment verification");
81136

82137
// Find the product
83138
// TODO temporary for testing retrieve product name from developer payload, later switch to productId
84139
$dp = json_decode($playPurchase->developerPayload);
85140
$productName = $dp->sku;
86-
87141
$product = Product::where(["name" => $productName])->first();
142+
88143
// $product = Product::where(["name" => $playPurchase->productId])->first();
89144
if (!$product){
90-
return $this->getResponse(self::RESULT_ERR_INVALID_PRODUCT);
145+
return self::RESULT_ERR_INVALID_PRODUCT;
91146
}
92147

93148
// Issue product
@@ -97,7 +152,7 @@ public function postAndroidPaymentVerification(Request $request)
97152
// Update order
98153
$orderPlayInapp->update(['license_id' => $license->id]);
99154

100-
return $this->getResponse(self::RESULT_OK);
155+
return self::RESULT_OK;
101156
}
102157

103158

@@ -108,6 +163,23 @@ private function getResponse($code)
108163
return json_encode($response);
109164
}
110165

166+
private function getResponseForMultiplePurchases(array $allResponseCodes)
167+
{
168+
$response = new \stdClass();
169+
$response->responseCode = self::RESULT_MULTIPLE_PURCHASES;
170+
$response->purchasesResponseCodes = $allResponseCodes;
171+
return json_encode($response);
172+
}
173+
174+
/***************************************/
175+
/************* APPLE *****************/
176+
/***************************************/
177+
178+
/**
179+
* Main processing method of Apple AppStore transactions
180+
* @param Request $request
181+
* @return string
182+
*/
111183
public function postApplePaymentVerification(Request $request)
112184
{
113185
$response = new \stdClass();

app/Http/Controllers/QaController.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Phonex\Jobs\CreateUserWithSubscriber;
88
use Phonex\Jobs\IssueProductLicense;
99
use Phonex\Jobs\RefreshSubscribers;
10+
use Phonex\Model\OrderPlayInapp;
1011
use Phonex\Model\Product;
1112
use Phonex\Subscriber;
1213
use Phonex\User;
@@ -18,8 +19,9 @@ public function QaController(){
1819

1920
public function getInfo()
2021
{
21-
$user = User::findByUsername("cburner2015");
22-
RefreshSubscribers::refreshSingleUser($user);
22+
dd(OrderPlayInapp::orderIdExists('transactionId.android.test.purchased2', User::findByUsername('test318')));
23+
// $user = User::findByUsername("cburner2015");
24+
// RefreshSubscribers::refreshSingleUser($user);
2325
}
2426

2527
private function rec($a){

app/Http/routes.php

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
Route::get('products/list-from-licenses', 'Api\ProductController@getLicensesProducts'); // List arbitrary user's products by providing license ids
5050
Route::any('purchase/appstore/payment-verif', 'Api\PurchaseController@postApplePaymentVerification');
5151
Route::any('purchase/play/payment-verif', 'Api\PurchaseController@postAndroidPaymentVerification');
52+
Route::any('purchase/play/payments-verif', 'Api\PurchaseController@postAndroidPaymentsVerification');
5253
});
5354

5455
// Authenticated pages using client credentials

app/Model/OrderPlayInapp.php

+11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php namespace Phonex\Model;
22

33
use Illuminate\Database\Eloquent\Model;
4+
use Phonex\User;
45

56
class OrderPlayInapp extends Model{
67
protected $table = 'orders_play_inapp';
@@ -10,4 +11,14 @@ class OrderPlayInapp extends Model{
1011
protected $fillable = ['license_id'];
1112

1213
public $timestamps = false;
14+
15+
/* Helper functions*/
16+
public static function orderIdExists($playOrderId)
17+
{
18+
return OrderPlayInapp::where('play_order_id', $playOrderId)
19+
// ->where('user_id', $user->id)
20+
// ->whereNotNull('license_id')
21+
->count() > 0;
22+
}
23+
1324
}

app/Purchase/PlayPurchase.php

+9-3
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,16 @@ class PlayPurchase
3030
public $appVersion;
3131
public $itemType;
3232

33-
public static function fromJson($json)
33+
34+
/**
35+
* Takes jsonObject input (after json_decode($json, true) has been passed)
36+
* @param $jsonObject
37+
* @return null|PlayPurchase
38+
*/
39+
public static function fromJsonObject(array $jsonObject)
3440
{
35-
$jsonObject = json_decode($json, true);
36-
if ($jsonObject ===null){
41+
// $jsonObject = json_decode($json, true);
42+
if ($jsonObject === null){
3743
return null;
3844
}
3945
$purchaseJson = $jsonObject['INAPP_PURCHASE_DATA'];

gulpfile.js

+1-8
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,5 @@ var elixir = require('laravel-elixir');
1212
*/
1313

1414
elixir(function(mix) {
15-
16-
17-
mix.less([
18-
// a directory in resources/less/assets/
19-
'less/AdminLTE.less',
20-
"less/skins/skin-blue.less",
21-
"less/skins/skin-yellow-light.less"
22-
]);
15+
mix.less('app.less');
2316
});

0 commit comments

Comments
 (0)