예제 #1
0
 /**
  * Creates a new "refund" in Realex's systems.
  *
  * Sends a 'receipt-out' request to Realex which creates a new payment at Realex.
  *
  * This also logs the transaction into the \Entities\RealexTransaction table,
  * and returns that object which can be queried for the request and transaction
  * state.
  *
  * If $this->_fake_transactions is true then it skips the Realex request and returns with
  * success after performing all normal database operations as if the request was sent.
  * @see $_fake_transactions
  *
  * @param \Entities\RealexCard $card
  * @param int|float $amount the amount to be withdrawn from the card, in the biggest unit of the currency,
  *    e.g. in euro or dollar and not in cent, then conversion is made inside the method
  * @return CreditcardTransaction The resultant CreditcardTransaction object
  * @throws OSS_PaymentProcessor_Exception
  */
 public function paymentOut($card, $amount)
 {
     $rqTimeStamp = $this->getTimeStamp();
     // we're about to perform payment which means that the cerdit card should exist
     if (!$card instanceof Creditcard) {
         $this->_log("PROG ERROR - expecting instance of Creditcard", OSS_Log::ERR);
         throw new OSS_PaymentProcessor_Exception('System Failure - our technical staff have been notified');
     }
     $rtrans = new \Entities\RealexTransaction();
     $rtrans->setRequestType('payment-out');
     $rtrans->setPayer($card->getPayer());
     $rtrans->getcard($card);
     $rtrans->setAmount($amount);
     $rtrans->setAccount($this->_account);
     $rtrans->setState(\Entities\RealexTransaction::STATE_INIT);
     $rtrans->setRequest("");
     $rtrans->setCreated(new \DateTime());
     $rtrans->setUpdated(new \DateTime());
     $rtrans->setIsFake(0);
     $this->getD2EM()->persist($rtrans);
     $this->getD2EM()->flush();
     $this->_log("[RTRANS: {$rtrans->getId()}] Realex::paymentOut() - transaction set to STATE_INIT");
     // we're about to perform payment which means that the cerdit card paygate state should be insync
     if ($card->etState() != \Entities\RealexCard::STATE_INSYNC) {
         $rtrans->setResult(999);
         throw new OSS_PaymentProcessor_Realex_Receipt_Exception($rtrans, OSS_PaymentProcessor_Exception::ERR_INCONSISTANT_PAYGATE_STATE);
     }
     $amount = (int) ($amount * 100);
     $rqOrderId = self::createOrderId($rtrans);
     $payerRef = $card->getPayer()->getPayerref();
     $cardRef = $card->getCardref();
     $rqHash = OSS_PaymentProcessor_Realex_Hash::payment($rqTimeStamp, $this->getMerchantId(), $rqOrderId, $amount, 'EUR', $payerRef, $this->getMerchantSecret());
     $refundHash = OSS_PaymentProcessor_Realex_Hash::refund($this->getRefundPassword(), $this->getMerchantSecret());
     $reqXML = "<request type='payment-out' timestamp='{$rqTimeStamp}'>\n                      <merchantid>" . $this->getMerchantId() . "</merchantid>\n                      <account>{$this->_account}</account>\n                      <orderid>{$rqOrderId}</orderid>\n                      <amount currency='EUR'>{$amount}</amount>\n                      <payerref>{$payerRef}</payerref>\n                      <paymentmethod>{$cardRef}</paymentmethod>\n                      <sha1hash>{$rqHash}</sha1hash>\n                      <refundhash>{$refundHash}</refundhash>\n                  </request>";
     $rtrans->setRequest($amount);
     $rtrans->setState(\Entities\RealexTransaction::STATE_PRESEND);
     $rtrans->setUpdated(new \DateTime());
     $this->getD2EM()->flush();
     $this->_log("[RTRANS: {$rtrans->getId()}] Realex::paymentOut() - transaction set to STATE_PRESEND\n\n{$reqXML}\n\n");
     if ($this->_fake_transactions) {
         $this->_log("[RTRANS: {$rtrans->getId()}] Realex::paymentOut() - faking transaction");
         return $this->_completeFakeTransation($rtrans);
     }
     $this->_sendRequest($rtrans, $reqXML);
     // can throw OSS_PaymentProcessor_Realex_Receipt_Exception()
     return $rtrans;
 }