I am trying to create a paypal payment page, but for some reason when I try to add a custom web profile to the payment the option of checking out as a guest suddenly disappears.
First I am creating the web profile this way:
$flowConfig = new FlowConfig();
$flowConfig
->setLandingPageType("billing")
->setBankTxnPendingUrl("...");
$presentation = new Presentation();
$presentation
->setLogoImage("...")
->setBrandName("...")
->setLocaleCode("...");
$inputFields = new InputFields();
$inputFields
->setNoShipping(1)
->setAddressOverride(0);
$webProfile = new WebProfile();
$webProfile->setName("PROFILE" . uniqid())
->setFlowConfig($flowConfig)
->setPresentation($presentation)
->setInputFields($inputFields);
$request = clone $webProfile;
try {
$createProfileResponse = $webProfile->create($apiContext);
} catch (PayPal\Exception\PayPalConnectionException $ex) {
...
}
$profileId = $createProfileResponse->getId();
Then, I have updated the payment code in this way
$paypalPayment = new PayPalPayment();
$paypalPayment->setIntent("sale");
$paypalPayment->setPayer($payer);
$paypalPayment->setRedirectUrls($redirectUrls);
$paypalPayment->setTransactions(array($transaction));
$paypalPayment->setExperienceProfileId($profileId);
The weird thing is that if I comment the last line I can perform payments as a guest without any issue. If, instead, I leave it this way, I get the customized page but the "Check out as a guest" button is replaced by "Create an account".
Do I really have to choose between having a customized checkout page and the possibility to perform payments without creating paypal accounts? Or am I missing something? I didn't find anything related to this issue in the documentation nor here in stackoverflow, and it seems at least strange!
Thank you
Are you using Express Checkout? It looks like recurring payments without a PayPal account are only compatible with Website Payments Pro accounts.
You can still create recurring payments with EC but they will need a PayPal account to accept them, no guest checkout allowed by the looks of it.
https://www.paypal-community.com/t5/Merchant-services-Archive/How-to-accept-recurring-payments-from-buyers-who-don-t-have-a/td-p/178232
Related
I'm using Memberpress and Memberpress Corporate on my WordPress site and I'm trying to add a custom function when a member signs up under a specific membership type or purchases a specific membership type. When this happens I need to grab the corporate account ID and do something with it.
I'm using the hook mepr-event-transaction-completed as this fires for both recurring and non-recurring transactions, though I also tried mepr-event-non-recurring-transaction-completed just to be sure.
This is my code:
$transaction = $event->get_data();
$membership_type_ids = array(1, 2, 4);
if (in_array($transaction->product_id, $membership_type_ids) && $transaction->txn_type == 'payment') {
$org_id = $transaction->corporate_account_id;
my_custom_function($org_id);
}
When the user is signing up for this membership type with a subscription, this is no problem, I can retrieve this, however if they are signing up with a one-time non-recurring transaction, the corporate account id is returning as 0, even though when I go to check the database, there is a corporate account id there.
Does the corporate account id get set at a different time for non-recurring transactions?
Okay, so after speaking to Memberpress, it turns out this just doesn't get set at the right time.
I used a workaround as so:
if($transaction->corporate_account_id !== "0" && $transaction->corporate_account_id !== 0) {
//some irrelevant code here about what to do if the corporate id actually works
} else {
write_log('sending cron to add new user due to corporate id returning as 0, please check in 2 minutes. tran_num = '.$transaction->trans_num);
wp_schedule_single_event( strtotime("+2 minutes"), 'send_fix_for_zero_transaction', array($transaction),false );
return;
}
add_action( 'send_fix_for_zero_transaction', 'single_transaction_create_corporate' );
function single_transaction_create_corporate($transaction) {
//NOTE: this function is only used it a one-time transaction is created in the backend to create a corporate membership, because there is a bug in memberpress that means the corporate_id isn't sent back by the event. This event will only fire if that is the case, otherwise this is handled by rc_setup_new_org. This should eventually be deprecated when Memberpress fix their issues.
$trans_num = $transaction->trans_num;
$full_trans = MeprTransaction::get_one_by_trans_num($trans_num);
//do whatever you need to do with the transaction here, you have the number now
}
I am working on Square payment gateway and I created three steps creating a customer, creating a card, and then making a payment.
$create_customer_request = new \Square\Models\CreateCustomerRequest();
$address = new \Square\Models\Address();
$address->setAddressLine1($ship_address);
$address->setPostalCode($_POST['ship_postcode']);
$address->setCountry('US');
$create_customer_request->setGivenName($_POST['f_name']);
$create_customer_request->setFamilyName($_POST['f_name']);
$create_customer_request->setEmailAddress($_POST['email']);
$create_customer_request->setAddress($address);
$create_customer_request->setPhoneNumber($_POST['phone']);
$create_customer_request->setReferenceId($_POST['f_name']."-customer-".rand(10,15));
$create_customer_request->setNote('A customer');
$custcreateapiResponse = $client->getCustomersApi() >createCustomer($create_customer_request);
$custcreateapiResponse->isSuccess();
$_SESSION['temp_customer_id'] = $cust_res->getCustomer()->getId();
creating a card request
$body_card = new \Square\Models\CreateCustomerCardRequest($_POST['nonce']);
$card_api_response = $client->getCustomersApi()->createCustomerCard($_SESSION['temp_customer_id'], $body_card);
making a payment
$payments_api = $client->getPaymentsApi();
$money->setAmount(10);
$money->setCurrency('USD');
$pay_body = new \Square\Models\CreatePaymentRequest($_POST['nonce'],uniqid(),$money);
$pay_body->setCustomerId($_SESSION['temp_customer_id']);
$response = $client->getPaymentsApi()->createPayment($pay_body);
The issue I am having right now, I need to make two requests with the Nonce token but the system doesn't allow me to do it for the Square payment gateway. Don't know what to do now, Any kind of help will be appreciated. Pardon me for any mistakes here.
I tried many solutions from the internet but none of them work for me, so I try logic by myself. I know it's not a good approach, however, it works for me
in payment form, I create another hidden field
<input type="hidden" id="card-nonce-1" name="nonce1">
create a new function in sq-payment-form.js
function onGetCardNoncesecond(event) {
event.preventDefault();
paymentForm.requestCardNonce();
}
and put the value in a hidden field and submit and use it. Any suggestion would be appreciated for the betterment.
OK, I've been banging my head against this for a few days now. I'm building a payment process into a PHP application which will allow for upselling products after a customer approves a payment.
I can get the payment charged to the customer without an issue, but if they select any kind of upsell product which requires the order value to change, then I get errors even though it is following to the letter what was in the documentation I could find...
Below is the test function I'm using, this is the function which is called when the user is redirected back to the website AFTER approving the payment.
public function confirmOrder($payer_id, $payment_id, $incentives = false){
//GET PAYMENT
$payment = Payment::get($payment_id, $this->apiContext);
//CREATE EXECUTION WITH PAYER ID
$execution = new PaymentExecution();
$execution->setPayerId($payer_id);
//APPLY PAYMENT AMOUNT - Original amount was 7.00
$amount = new Amount();
$amount = $amount->setCurrency('GBP')->setTotal('8.00');
//PATCH REPLACE
$patchReplace = new Patch();
$patchReplace = $patchReplace->setOp('replace')->setPath('/transactions/0/amount')->setValue($amount);
//CREATE PATCH OBJECT
$patchRequest = new PatchRequest();
$patchRequest = $patchRequest->setPatches(array($patchReplace));
try {
$payment->update($patchRequest, $this->apiContext);
} catch (PayPalConnectionException $ex) {
return "PATCH ERROR: State(" . $payment->getState() . ") ".$ex->getData();
}
}
This isn't the final code I will use but right now I'm just trying to get an order updated before I build in more of the logic. This code gives me the following error:
PATCH ERROR: State(created) {"name":"PAYMENT_STATE_INVALID","message":"This request is invalid due to the current state of the payment","information_link":"https://developer.paypal.com/webapps/developer/docs/api/#PAYMENT_STATE_INVALID","debug_id":"9caacdc1d652b"}
You can see I'm outputting the getState() which is coming back as 'created' which would normally be fine for updating in everything I can find but it is still failing.
Does anyone else have experience with the PayPal PHP SDK and could help point me in the right direction?
In PayPal, once the user has approved the payment from the consent screen, the amount cannot be changed, as you can understand the user agreed to pay only the amount he/she saw on the consent screen. Modifying the amount after user approves it, is not allowed, and that's why you are seeing that state exception, as the state is already approved.
Anyway, looking at your scenario, I think you might be interested in either creating order, or capture, instead of sale.
Also, in our PayPal-PHP-SDK, there are a lot of interesting documents that could help you understand PHP-SDK better. We also provide a lot of runnable samples, that you could setup in your local machine, by one command only.
I'm using Stripe's php library to create a customer with a subscription that contains a coupon. I don't want to add the coupon at the customer level, I want to add it at the subscription level. The below code is what I'm currently using and according to their support, this should work, but it doesn't. I was hoping someone will be able to help.
$params = array(
'card'=>'SOME_TOKEN_FROM_JS_LIBRARY',
'plan'=>'valid_plan_id',
'coupon'=>'valid_coupon_id'
);
$c = Stripe_Customer::create($params);
if(!empty($params['coupon'])){
$c->updateSubscription(array(
'plan'=>$params['plan'],
'coupon'=>$params['coupon']
));
}
This successfully creates the customer and charges the card with the coupon applied.
Ended up going with the code below, it does what I want it to do. Also, the goal with the code below is to delete the customer if the charge fails for whatever reason, so I'm not left with customers that don't belong anywhere.
$_c = Stripe_Customer::create($params);
try{
$_c->subscriptions->create(array('plan'=>$plan, 'coupon'=>$coupon));
}catch(Exception $e){
$_c->delete();
throw new Exception($e->getMessage());
}
$c = Stripe_Customer::retrieve($_c->id); //to get the customer object with the latest data
I am using magento 1.7.Can anyone help/advise on this??
Also using EPDQ Barclaycard module.
Everything seems ok with capturing payments, however when I go to checkout fill in all the details up to Payment Information select card type and hit continue, then place order a new order email has been sent but it hasnt been paid for yet!
Is there anyway that this can be prevented till payment has been captured via Barclaycard?
Have I missed something?
Thanks in advance
Magento sends email order confirmations as soon as the order is placed. If you are redirecting the user to a payment gateway after the order has been placed but not paid for you will need to modify your payment module to use magento's payment redirect setup to get it to ignore the confirmation email (See Mage_Checkout_Model_Type_Onepage class saveOrder() method).
You should see some code like;
/**
* a flag to set that there will be redirect to third party after confirmation
* eg: paypal standard ipn
*/
$redirectUrl = $this->getQuote()->getPayment()->getOrderPlaceRedirectUrl();
/**
* we only want to send to customer about new order when there is no redirect to third party
*/
if (!$redirectUrl && $order->getCanSendNewEmailFlag()) {
try {
$order->sendNewOrderEmail();
} catch (Exception $e) {
Mage::logException($e);
}
}
So this gives you a few options. Extend your payment module so that it sets the order place redirect url, but this might mess up your payment module depending on how it was coded or you could extend the above class into your own module (do not mod the core), override the saveOrder() method and check the payment method in the if statement shown above a bit like;
if (!$redirectUrl && $order->getPayment()->getMethod() != 'your_payment_method' && $order->getCanSendNewEmailFlag()) {
try {
$order->sendNewOrderEmail();
} catch (Exception $e) {
Mage::logException($e);
}
}
You would then to handle IPN notification to get it to send the email when a successful payment IPN is received, I would suggest you take a look at the PayPal Standard module that ships with Magento for some pointers as this is exactly how it works. I am surprised the EPDQ module you have does not work like this already, might be worth contacting them and highlighting the issue.