Data returned from Facebook but query won't trigger

Cupara

Well-known member
Upon the successful purchase of points the order status is updated to settled but the query to update the user table won't trigger.

xfpoints_fbcall.php
Code:
<?php
$app_id = *REMOVED*;
$app_secret = *REMOVED*;

// Validate request is from Facebook and parse contents for use.
$request = parse_signed_request($_POST['signed_request'], $app_secret);

// Get request type.
// Two types:
//   1. payments_get_items.
//   2. payments_status_update.
$request_type = $_POST['method'];

// Setup response.
$response = '';

if ($request_type == 'payments_get_items') {
  // Get order info from Pay Dialog's order_info.
  // Assumes order_info is a JSON encoded string.
  $order_info = json_decode($request['credits']['order_info'], true);

  // Get item id.
  $item_id = $order_info['item_id'];

  // Simulutates item lookup based on Pay Dialog's order_info.
  if ($item_id == '100') {
    $item = array(
      'title' => '100 Points for 1 Facebook Credit',
      'description' => 'Purchasing 100 Points for 1 Facebook Credit',
      'amount' => 100,
      // Price must be denominated in credits.
      'price' => 1,
      'image_url' => 'https://www.fbforums.co/shillings.jpg',
      'userid' => $order_info['userid'],
      'username' => $order_info['username'],
      'theory_points' => $order_info['theory_points']
    );

    // Construct response.
    $response = array(
                  'content' => array(
                                 0 => $item,
                               ),
                  'method' => $request_type,
                );
    // Response must be JSON encoded.
    $response = json_encode($response);
  }

} else if ($request_type == "payments_status_update") {
  // Get order details.
  $order_details = json_decode($request['credits']['order_details'], true);

  // Determine if this is an earned currency order.
  $item_data = json_decode($order_details['items'][0]['data'], true);
  $earned_currency_order = (isset($item_data['modified'])) ?
                             $item_data['modified'] : null;

  // Get order status.
  $current_order_status = $order_details['status'];

  if ($current_order_status == 'placed') {
    // Fulfill order based on $order_details unless...

    if ($earned_currency_order) {
      // Fulfill order based on the information below...
      // URL to the application's currency webpage.
      $product = $earned_currency_order['product'];
      // Title of the application currency webpage.
      $product_title = $earned_currency_order['product_title'];
      // Amount of application currency to deposit.
      $product_amount = $earned_currency_order['product_amount'];
      // If the order is settled, the developer will receive this
      // amount of credits as payment.
      $credits_amount = $earned_currency_order['credits_amount'];
    }

    $next_order_status = 'settled';

    // Construct response.
    $response = array(
                  'content' => array(
                                 'status' => $next_order_status,
                                 'order_id' => $order_details['order_id'],
                               ),
                  'method' => $request_type,
                );
    // Response must be JSON encoded.
    $response = json_encode($response);

  } else if ($current_order_status == 'disputed') {
    // 1. Track disputed item orders.
    // 2. Investigate user's dispute and resolve by settling or refunding the order.
    // 3. Update the order status asychronously using Graph API.

  } else if ($current_order_status == 'refunded') {
    // Track refunded item orders initiated by Facebook. No need to respond.

  } else if ($current_order_status == 'settled') {

    // Verify that the order ID corresponds to a purchase you've fulfilled, then…

    // Get order details.
    $order_details = json_decode($request['credits']['order_details'], true);

    // Construct response.
    $response = array(
                  'content' => array(
                                 'status' => 'settled',
                                 'order_id' => $order_details['order_id'],
                               ),
                  'method' => $request_type,
                );
    // Response must be JSON encoded.
    $response = json_encode($response);

    $userid = 61;

    $pointsEarned = 100+100;

    $processor = 'xfPoints_Model_Currency';

    print($pointsEarned);
    print($userid);

    return $processor->updateUserPoints($pointsEarned, $userid);

  } else {
    // Track other order statuses.

  }
}

// Send response.
echo $response;

// These methods are documented here:
// https://developers.facebook.com/docs/authentication/signed_request/
function parse_signed_request($signed_request, $secret) {
  list($encoded_sig, $payload) = explode('.', $signed_request, 2);

  // decode the data
  $sig = base64_url_decode($encoded_sig);
  $data = json_decode(base64_url_decode($payload), true);

  if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
    error_log('Unknown algorithm. Expected HMAC-SHA256');
    return null;
  }

  // check sig
  $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
  if ($sig !== $expected_sig) {
    error_log('Bad Signed JSON signature!');
    return null;
  }

  return $data;
}

function base64_url_decode($input) {
  return base64_decode(strtr($input, '-_', '+/'));
}

If you look under 'else if ($current_order_status == 'settled') {' you will see my $proessor but not grasping why it won't trigger the query.
 
You never created a model instance. You just defined which model you wanted to use. I'm surprised PHP isn't yelling at you for attempting to access a function on a non-object.
 
LOL OMG, can't believe I did that.

I'm surprised too but then again this is outside of the library, it is in the root.
 
That is because it is the same. I've explained myself and even did what you suggested. Didn't work so I removed it. Not hard to tell what I'm trying to do. Use a callback file in the root to write to the database upon transaction coming back settled.
 
That is because it is the same. I've explained myself and even did what you suggested. Didn't work so I removed it. Not hard to tell what I'm trying to do. Use a callback file in the root to write to the database upon transaction coming back settled.
The above code will error out for the reasons already stated. You cannot try to use a string as an object in PHP. There are plenty of ways to interpret 'added the call for the model', so its not directly apparent what you did.

My largest suggestion right now would be to test what data you are actually receiving from Facebook, since its appearing that you ever hitting your if statement.
 
  • Like
Reactions: Bob
I'm not getting errors at all. I tried using getModelFromCache as I'm not aware of any other methods to call the model. As far as I know the userid and amount are not even passing or I'm trying to grab them all wrong.
 
If you reverted your code and you aren't getting errors, you are never reaching the that portion of code. Debug what data you are actually receiving from Facebook and scrutinize your if statements.
 
getModelFromCache probably won't work either... that function is defined in the XenForo Controller, and you aren't calling that either.

The correct way to call a model outside of the controller is:

$processor = XenForo_Model::create('xfPoints_Model_Currency');
 
Trying but can't figure out why userid or amount is not being passed to facebook. It reaches that if statement because it updates my screen to show that status is now settled.

I have found many Facebook API integration for Zend so I am going to try an implement that and use it instead of this straight callback file.
 
App is not responding error now. LOL

I may have altered something in the file. I'll get it fixed and try again.
 
Top Bottom