Esempio n. 1
0
 public function willRefundCharge(PhabricatorUser $actor, PhortunePaymentProvider $provider, PhortuneCharge $charge, PhortuneCurrency $amount)
 {
     if (!$amount->isPositive()) {
         throw new Exception(pht('Trying to refund non-positive amount of money!'));
     }
     if ($amount->isGreaterThan($charge->getAmountRefundableAsCurrency())) {
         throw new Exception(pht('Trying to refund more money than remaining on charge!'));
     }
     if ($charge->getRefundedChargePHID()) {
         throw new Exception(pht('Trying to refund a refund!'));
     }
     if ($charge->getStatus() !== PhortuneCharge::STATUS_CHARGED && $charge->getStatus() !== PhortuneCharge::STATUS_HOLD) {
         throw new Exception(pht('Trying to refund an uncharged charge!'));
     }
     $refund_charge = PhortuneCharge::initializeNewCharge()->setAccountPHID($this->getAccount()->getPHID())->setCartPHID($this->getPHID())->setAuthorPHID($actor->getPHID())->setMerchantPHID($this->getMerchant()->getPHID())->setProviderPHID($provider->getProviderConfig()->getPHID())->setPaymentMethodPHID($charge->getPaymentMethodPHID())->setRefundedChargePHID($charge->getPHID())->setAmountAsCurrency($amount->negate());
     $charge->openTransaction();
     $charge->beginReadLocking();
     $copy = clone $charge;
     $copy->reload();
     if ($copy->getRefundingPHID() !== null) {
         throw new Exception(pht('Trying to refund a charge which is already refunding!'));
     }
     $refund_charge->save();
     $charge->setRefundingPHID($refund_charge->getPHID());
     $charge->save();
     $charge->endReadLocking();
     $charge->saveTransaction();
     return $refund_charge;
 }
 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);
     }
 }