function testSet() { if ($this->paypal_username) { $pp = new PaypalSeed($this->cash_user_id, $this->paypal_connection_id); $redirect_url = $pp->setExpressCheckout('13.26', 'order_sku', 'this is the best order ever', 'http://localhost', 'http://localhost'); $this->assertTrue($redirect_url); //$redirect = CASHSystem::redirectToUrl($redirect_url); //echo $redirect; } }
protected function cancelOrder($id, $user_id = false) { $order_details = $this->getOrder($id, true); // if we send a user id, make sure that user matches the order if ($user_id) { if ($user_id != $order_details['user_id']) { return false; } } switch ($order_details['connection_type']) { case 'com.paypal': $pp = new PaypalSeed($order_details['user_id'], $order_details['connection_id']); $refund_details = $pp->doRefund($order_details['service_transaction_id'], 'This order was cancelled by the seller.'); // check initial refund success if (!$refund_details) { return false; } else { // make sure the refund went through fully, return false if not if (isset($refund_details['REFUNDINFO'])) { if ($refund_details['REFUNDINFO']['REFUNDSTATUS'] == 'none') { return false; } } $this->editOrder($id, false, 1, "Cancelled " . date("F j, Y, g:i a T") . "\n\n" . $order_details['notes']); $this->editTransaction($order_details['transaction_id'], false, false, false, false, false, false, false, 'refunded'); return true; // NOTE: // we aren't restocking physical goods for a few reasons: // 1. cancellations should be less common than sales // 2. lack of inventory is a common reason to cancel, restocking makes it worse // 3. manually re-adding stock isn't hard // 4. if an order is a return of damaged goods, you won't restocking // 5. f**k it } break; default: return false; } }
} else { exit; } } } else { $_SESSION['seed_error'] = 'No matching product was found.'; $_SESSION['seed_state_payment'] = 'error'; } } else { $_SESSION['seed_error'] = 'No product was specified.'; $_SESSION['seed_state_payment'] = 'error'; } } else if (isset($_GET['token']) && isset($_GET['PayerID'])) { // data returned from Paypal include_once($PaypalSeed_location); $pp = new PaypalSeed($paypal_address,$paypal_key,$paypal_secret); $_SESSION['cash_primary_request'] = $pp->getExpressCheckout(); $_SESSION['seed_response'] = $pp->doExpressCheckout(); $_SESSION['seed_details'] = $pp->getExpressCheckout(); // handle all processing then redirect to self, cleaning the URL switch ($_SESSION['seed_details']['CHECKOUTSTATUS']) { case 'PaymentActionCompleted': if ($_SESSION['seed_response']['PAYMENTINFO_0_PAYMENTSTATUS'] == 'Completed' || $_SESSION['seed_response']['PAYMENTINFO_0_PAYMENTSTATUS'] == 'In-Progress' || $_SESSION['seed_response']['PAYMENTINFO_0_PAYMENTSTATUS'] == 'Processed' || $_SESSION['seed_response']['PAYMENTINFO_0_PAYMENTSTATUS'] == 'Pending') { include_once($DBASeed_location); include_once($TransactionSeed_location); $db = new DBASeed(DB_HOSTNAME,DB_USERNAME,DB_PASSWORD,DB_DATABASE); $transaction = new TransactionSeed($db);
protected function finalizeRedirectedPayment($order_id, $creation_date, $direct_post_details = false, $session_id = false) { $order_details = $this->getOrder($order_id); $transaction_details = $this->getTransaction($order_details['transaction_id']); $connection_type = $this->getConnectionType($transaction_details['connection_id']); $r = new CASHRequest(); $r->startSession(false, $session_id); $finalize_url = $r->sessionGet('payment_finalize_url'); if ($finalize_url) { $r->sessionClear('payment_finalize_url'); } switch ($connection_type) { case 'com.paypal': if (isset($_GET['token'])) { if (isset($_GET['PayerID'])) { $pp = new PaypalSeed($order_details['user_id'], $transaction_details['connection_id'], $_GET['token']); $initial_details = $pp->getExpressCheckout(); if ($initial_details['ACK'] == 'Success') { $order_totals = $this->getOrderTotals($order_details['order_contents']); if ($initial_details['AMT'] >= $order_totals['price']) { $final_details = $pp->doExpressCheckout(); if ($final_details) { // look for a user to match the email. if not present, make one $user_request = new CASHRequest(array('cash_request_type' => 'people', 'cash_action' => 'getuseridforaddress', 'address' => $initial_details['EMAIL'])); $user_id = $user_request->response['payload']; if (!$user_id) { $user_request = new CASHRequest(array('cash_request_type' => 'system', 'cash_action' => 'addlogin', 'address' => $initial_details['EMAIL'], 'password' => time(), 'is_admin' => 0, 'display_name' => $initial_details['FIRSTNAME'] . ' ' . $initial_details['LASTNAME'], 'first_name' => $initial_details['FIRSTNAME'], 'last_name' => $initial_details['LASTNAME'], 'address_country' => $initial_details['COUNTRYCODE'])); $user_id = $user_request->response['payload']; } // deal with physical quantities if ($order_details['physical'] == 1) { $order_items = json_decode($order_details['order_contents'], true); if (is_array($order_items)) { foreach ($order_items as $i) { if ($i['available_units'] > 0 && $i['physical_fulfillment'] == 1) { $item = $this->getItem($i['id']); if ($i['variant']) { $variant_id = 0; $variant_qty = 0; if ($item['variants']) { foreach ($item['variants']['quantities'] as $q) { if ($q['key'] == $i['variant']) { $variant_id = $q['id']; $variant_qty = $q['value']; break; } } if ($variant_id) { $this->editItemVariant($variant_id, max($variant_qty - $i['qty'], 0), $i['id']); } } } else { $available_units = $this->editItem($i['id'], false, false, false, false, false, max($item['available_units'] - $i['qty'], 0)); } } } } } // record all the details if ($order_details['digital'] == 1 && $order_details['physical'] == 0) { // if the order is 100% digital just mark it as fulfilled $is_fulfilled = 1; } else { // there's something physical. sorry dude. gotta deal with it still. $is_fulfilled = 0; } $this->editOrder($order_id, $is_fulfilled, 0, false, $initial_details['COUNTRYCODE'], $user_id); $this->editTransaction($order_details['transaction_id'], strtotime($final_details['TIMESTAMP']), $final_details['CORRELATIONID'], json_encode($initial_details), json_encode($final_details), 1, $final_details['PAYMENTINFO_0_AMT'], $final_details['PAYMENTINFO_0_FEEAMT'], 'complete'); // empty the cart at this point $this->emptyCart($session_id); // TODO: add code to order metadata // bit of a hack, hard-wiring the email bits: try { $personalized_message = ''; if ($order_details['element_id']) { $element_request = new CASHRequest(array('cash_request_type' => 'element', 'cash_action' => 'getelement', 'id' => $order_details['element_id'])); if ($element_request->response['payload']) { if (isset($element_request->response['payload']['options']['message_email'])) { if ($element_request->response['payload']['options']['message_email']) { $personalized_message = $element_request->response['payload']['options']['message_email'] . "\n\n"; } } } } if ($order_details['digital']) { $addcode_request = new CASHRequest(array('cash_request_type' => 'element', 'cash_action' => 'addlockcode', 'element_id' => $order_details['element_id'])); if (!$finalize_url) { $finalize_url = CASHSystem::getCurrentURL(); } CASHSystem::sendEmail('Thank you for your order', $order_details['user_id'], $initial_details['EMAIL'], $personalized_message . "Your order is complete. Here are some details:\n\n**Order #" . $order_details['id'] . "** \n" . $initial_details['PAYMENTREQUEST_0_DESC'] . " \n Total: " . CASHSystem::getCurrencySymbol($order_details['currency']) . number_format($final_details['PAYMENTINFO_0_AMT'], 2) . "\n\n" . "\n\n" . '[View your receipt and any downloads](' . $finalize_url . '?cash_request_type=element&cash_action=redeemcode&code=' . $addcode_request->response['payload'] . '&element_id=' . $order_details['element_id'] . '&email=' . urlencode($initial_details['EMAIL']) . '&order_id=' . $order_details['id'] . ')', 'Thank you.'); } else { CASHSystem::sendEmail('Thank you for your order', $order_details['user_id'], $initial_details['EMAIL'], $personalized_message . "Your order is complete. Here are some details:\n\n**Order #" . $order_details['id'] . "** \n" . $initial_details['PAYMENTREQUEST_0_DESC'] . " \n Total: " . CASHSystem::getCurrencySymbol($order_details['currency']) . number_format($final_details['PAYMENTINFO_0_AMT'], 2) . "\n\n", 'Thank you.'); } } catch (Exception $e) { // TODO: handle the case where an email can't be sent. maybe display the download // code on-screen? that plus storing it with the order is probably enough } return $order_details['id']; } else { // make sure this isn't an accidentally refreshed page if ($initial_details['CHECKOUTSTATUS'] != 'PaymentActionCompleted') { $initial_details['ERROR_MESSAGE'] = $pp->getErrorMessage(); // there was an error processing the transaction $this->editOrder($order_id, 0, 1); $this->editTransaction($order_details['transaction_id'], strtotime($initial_details['TIMESTAMP']), $initial_details['CORRELATIONID'], false, json_encode($initial_details), 0, false, false, 'error processing payment'); return false; } else { // this is a successful transaction with the user hitting refresh // as long as it's within 30 minutes of the original return true, otherwise // call it false and allow the page to expire if (time() - strtotime($initial_details['TIMESTAMP']) < 180) { return true; } else { return false; } } } } else { // insufficient funds — user changed amount? $this->editOrder($order_id, 0, 1); $this->editTransaction($order_details['transaction_id'], strtotime($initial_details['TIMESTAMP']), $initial_details['CORRELATIONID'], false, json_encode($initial_details), 0, false, false, 'incorrect amount'); return false; } } else { // order reporting failure $this->editOrder($order_id, 0, 1); $this->editTransaction($order_details['transaction_id'], strtotime($initial_details['TIMESTAMP']), $initial_details['CORRELATIONID'], false, json_encode($initial_details), 0, false, false, 'payment failed'); return false; } } else { // user canceled transaction $this->editOrder($order_id, 0, 1); $this->editTransaction($order_details['transaction_id'], time(), false, false, false, 0, false, false, 'canceled'); return false; } } break; default: return false; } }
protected function finalizeRedirectedPayment($order_id, $creation_date, $direct_post_details = false) { $order_details = $this->getOrder($order_id); $transaction_details = $this->getTransaction($order_details['transaction_id']); $connection_type = $this->getConnectionType($transaction_details['connection_id']); switch ($connection_type) { case 'com.paypal': if (isset($_GET['token'])) { if (isset($_GET['PayerID'])) { $pp = new PaypalSeed($order_details['user_id'], $transaction_details['connection_id'], $_GET['token']); $initial_details = $pp->getExpressCheckout(); if ($initial_details['ACK'] == 'Success') { $order_totals = $this->getOrderTotals($order_details['order_contents']); if ($initial_details['AMT'] >= $order_totals['price']) { $final_details = $pp->doExpressCheckout(); if ($final_details) { // look for a user to match the email. if not present, make one $user_request = new CASHRequest(array('cash_request_type' => 'people', 'cash_action' => 'getuseridforaddress', 'address' => $initial_details['EMAIL'])); $user_id = $user_request->response['payload']; if (!$user_id) { $user_request = new CASHRequest(array('cash_request_type' => 'system', 'cash_action' => 'addlogin', 'address' => $initial_details['EMAIL'], 'password' => time(), 'is_admin' => 0, 'display_name' => $initial_details['FIRSTNAME'] . ' ' . $initial_details['LASTNAME'], 'first_name' => $initial_details['FIRSTNAME'], 'last_name' => $initial_details['LASTNAME'], 'address_country' => $initial_details['COUNTRYCODE'])); $user_id = $user_request->response['payload']; } // record the details to the order/transaction where appropriate $this->editOrder($order_id, 1, 0, false, $initial_details['COUNTRYCODE'], $user_id); $this->editTransaction($order_details['transaction_id'], $service_timestamp = strtotime($final_details['TIMESTAMP']), $service_transaction_id = $final_details['CORRELATIONID'], $data_sent = json_encode($initial_details), $data_returned = json_encode($final_details), $successful = 1, $gross_price = $final_details['PAYMENTINFO_0_AMT'], $service_fee = $final_details['PAYMENTINFO_0_FEEAMT'], $status = 'complete'); $addcode_request = new CASHRequest(array('cash_request_type' => 'element', 'cash_action' => 'addlockcode', 'element_id' => $order_details['element_id'])); // bit of a hack, hard-wiring the email bits: CASHSystem::sendEmail('Your download is ready', CASHSystem::getDefaultEmail(), $initial_details['EMAIL'], 'Your download of "' . $initial_details['L_PAYMENTREQUEST_0_NAME0'] . '" is ready and can be found at: ' . CASHSystem::getCurrentURL() . '?cash_request_type=element&cash_action=redeemcode&code=' . $addcode_request->response['payload'] . '&element_id=' . $order_details['element_id'] . '&email=' . urlencode($initial_details['EMAIL']), 'Thank you'); return true; } else { // make sure this isn't an accidentally refreshed page if ($initial_details['CHECKOUTSTATUS'] != 'PaymentActionCompleted') { $initial_details['ERROR_MESSAGE'] = $pp->getErrorMessage(); // there was an error processing the transaction $this->editOrder($order_id, 0, 1); $this->editTransaction($order_details['transaction_id'], $service_timestamp = strtotime($initial_details['TIMESTAMP']), $service_transaction_id = $initial_details['CORRELATIONID'], $data_sent = false, $data_returned = json_encode($initial_details), $successful = 0, $gross_price = false, $service_fee = false, $status = 'error processing payment'); return false; } else { // this is a successful transaction with the user hitting refresh // as long as it's within 30 minutes of the original return true, otherwise // call it false and allow the page to expire if (time() - strtotime($initial_details['TIMESTAMP']) < 180) { return true; } else { return false; } } } } else { // insufficient funds — user changed amount? $this->editOrder($order_id, 0, 1); $this->editTransaction($order_details['transaction_id'], $service_timestamp = strtotime($initial_details['TIMESTAMP']), $service_transaction_id = $initial_details['CORRELATIONID'], $data_sent = false, $data_returned = json_encode($initial_details), $successful = 0, $gross_price = false, $service_fee = false, $status = 'incorrect amount'); return false; } } else { // order reporting failure $this->editOrder($order_id, 0, 1); $this->editTransaction($order_details['transaction_id'], $service_timestamp = strtotime($initial_details['TIMESTAMP']), $service_transaction_id = $initial_details['CORRELATIONID'], $data_sent = false, $data_returned = json_encode($initial_details), $successful = 0, $gross_price = false, $service_fee = false, $status = 'payment failed'); return false; } } else { // user canceled transaction $this->editOrder($order_id, 0, 1); $this->editTransaction($order_details['transaction_id'], $service_timestamp = time(), $service_transaction_id = false, $data_sent = false, $data_returned = false, $successful = 0, $gross_price = false, $service_fee = false, $status = 'canceled'); return false; } } break; default: return false; } }