public function updateCharge(PhortuneCharge $charge) { $transaction_id = $charge->getMetadataValue('paypal.transactionID'); if (!$transaction_id) { throw new Exception(pht('Charge has no transaction ID!')); } $params = array('TRANSACTIONID' => $transaction_id); $result = $this->newPaypalAPICall()->setRawPayPalQuery('GetTransactionDetails', $params)->resolve(); $is_charge = false; $is_fail = false; switch ($result['PAYMENTSTATUS']) { case 'Processed': case 'Completed': case 'Completed-Funds-Held': $is_charge = true; break; case 'Partially-Refunded': case 'Refunded': case 'Reversed': case 'Canceled-Reversal': // TODO: Handle these. return; case 'In-Progress': case 'Pending': // TODO: Also handle these better? return; case 'Denied': case 'Expired': case 'Failed': case 'None': case 'Voided': default: $is_fail = true; break; } if ($charge->getStatus() == PhortuneCharge::STATUS_HOLD) { $cart = $charge->getCart(); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); if ($is_charge) { $cart->didApplyCharge($charge); } else { if ($is_fail) { $cart->didFailCharge($charge); } } unset($unguarded); } }