PayumBundle Paypal Express confirmation step - paypal

Is it possible to perform a custom action, such as checking a date, in payment confirm? I want that just after click the confirmation button do a query to database and depending on result confirm the payment to paypal or not.

Yes, it is possible. you have to overwrite the confirm order action.
You can pass your own to the factory.
<?php
$factory->create([
'payum.action.api.confirm_order' => new AcmeConfirmOrderAction(),
]);
If you are using symfony, register the action as service and add the tag:
acme_configrm_order_action:
class: AcmeConfirmOrderAction
tags:
- { name: payum.action, alias: payum.action.api.confirm_order, factory: paypal_express_checkout_nvp }
I've not tested the code but it should be something like this. You can test it works with console command: app/console payum:gateway:debug

Related

Perform extra validation after a Student signs into Moodle

I am hoping someone can point me in the right direction. We host a University Moodle site and we are looking for a way in which we can perform extra validation on a Student whenever they login. I will give a scenario.
We have an endpoint with a list of email addresses of students allowed to use the system, for example a list of Students who are fully paid up on tuition. Therefore, we are looking for a way to hook into the login process, perform this check and the allow the student to continue or redirect back to the login page with an error.
I would appreciate any advice on how we can achieve this. Thank you.
I found a solution to my problem. I ended up creating a custom Authentication plugin using the guidelines from https://docs.moodle.org/dev/Authentication_plugins. With that knowledge, I used the copied the folder in the Moodle installation path auth/none and used that as a shell for my new plugin. I went ahead and customized the plugin names to what I needed. Once that was done and once the plugin was installed and enabled from the Administrator Dashboard, I had something like this in my auth.php file:
// Required for all auth plugins
public function user_login($username, $password)
{
return false;
}
// Hooks in immediately after the User submits the login form
public function loginpage_hook()
{
$username = $_REQUEST['username'] ?? '';
/** CODE CHECKING IF USERNAME IS ALLOWED TO ACCESS MOODLE **/
/** FOR EXAMPLE CHECK IF USER PAID FEES **/
$userHasPaidFees = api_checks_if_user_paid_fees($username);
if ($userHasPaidFees ) {
// Returning true here proceeds with the
// normal Username/Password login combination
return true;
}
// If not, redirect them back to Login
// Or any other page and notify
redirect(
new moodle_url('/login/index.php'),
'Message telling user why they were not able to sign in',
null,
\core\output\notification::NOTIFY_ERROR
);
}
Thanks and I hope someone finds this useful.

Pass additional parameter to paypal button url

I created a paypal button to manage my subscriptions and I´m planning to use it with my own link. Im not using the javascript SDK
Pay now
I was able to find that you can pass the &custom=123 parameter
but when I fetch a single subscription with
https://api-m.paypal.com/v1/billing/subscriptions/123
I don´t see the value of custom but I do see it in the POST request to my IPN endpoint. that means Paypal is sending it.
how can I see this custom value in the subscription itself? thank you!
Either: change to using a JavaScript SDK subscribe button and provide your value in the createSubscription's custom_id field
Or: continue using the legacy Subscribe button/link and try querying a v1/payments sale or v2/payments capture using a completed transaction ID for the subscription (not a profile ID), which might map to containing that legacy Subscribe transaction's custom value
Try this
<button onclick="pay()">Pay now</button>
<script>
function pay() {
$.ajax({
url: "https://www.paypal.com/cgi-bin/webscr",
type: "get",
data: {
cmd: _s-xclick,
hosted_button_id: 0000,
custom: 123
},
success: function(response) {
//Do Something
},
error: function(xhr) {
//Do Something to handle error
}
});
}
</script>

PayPal API login error - "Sorry, we can't log you in.."

I am using the paypal api login with this:
paypal.use( ['login'], function (login) {
login.render ({
"appid":"myAppID",
"authend": "sandbox",
"scopes":"email",
"containerid":"lippButton",
"locale":"en-us",
"returnurl":"myReturnUrl"
});
});
when I click on lippButton paypal opens with forms for email and password. When they are filled in I get the error:
Sorry, we can't log you in. If you think there's a problem with your
account, contact us and we'll help resolve it.
Even though If I redirect the user to login/complete payment it is fine. Any ideas as to what the problem is?
EDIT:
Seems like it may just be the sandbox api is down. I went here:
https://devtools-paypal.com/guide/openid/php?success=true&env=sandbox
and clicked "Try it" then clicked on the link for step 2, which pops up an identical login form that I am using and the error message persists there as well.
EDIT:
Can anyone explain how I can log in to paypal, but not from their sandbox using my paypal credentials?
I found the problem. For anyone in the future with this same problem (I'm assuming many will because it is directly following their walk through), you seem to not be able to log in via "sandbox" mode (even though their provided code sample has authend: "sandbox" in it).
Simply put in your live credentials INSTEAD of your sandbox credentials. The log in should look like this (There should be no 'authend: "sandbox"' now):
paypal.use( ['login'], function (login) {
login.render ({
"appid":"myAppID", //Use your live client ID, not your sandbox client ID.
//No authend needed.
"scopes":"email",
"containerid":"lippButton",
"locale":"en-us",
"returnurl":"myReturnUrl"
});
});
And the login now works and allows you to login.

Cannot find realtime updates panel in the new App DashBoard

Where can we configure "Subscribing to Realtime Updates" in the new App Dashboard ?
It looks like the following documentation is not aligned with the new App dashboard
https://developers.facebook.com/docs/graph-api/real-time-updates
thanks
Payments and Payment subscriptions objects are appears in "Orders" tab: https://developers.facebook.com/x/apps/__appId__/payments/
But you can't configure actions field (oO)
For configure those fields and other objects, use Graph API.
For example, graph api explorer https://developers.facebook.com/tools/explorer
set type to POST
remove access_token input's value
set url __appID__/subscriptions?access_token=__appID__|__appSecret__&object=payments
add field:
object: (subscription object - user, payments, permissions, etc)
callback_url: your_url
verify_token: your_token
fields: (for payments actions,disputes are required)
Update: found, that this, old URL is still work:
https://developers.facebook.com/apps/__appID__/realtime?ref=nav

PayPal Adaptive Payments: two payments from one sender in two browser tabs

I use PayPal Adaptive Payments (parallel) on my website and I've encountered a strange problem with two payments in two different browser tabs from the same sender. The similar question was asked before, but nobody answered there.
The scenario which reproduces the problem
The user opens the first browser tab of the website and starts a payment process to the first seller.
PayPal's lightbox with Login button appears.
The user opens the second browser tab of the website and starts a payment process to the second seller.
Again, PyaPal's lightbox with Login button appears.
The user returns to the first browser tab and login to PayPal.
After login to PayPal in the first browser tab the user sees payment details to the second seller.
After login to PayPal in the second browser tab the user sees payment details to the second seller.
It seems that PayPal Adaptive Payments support only one transaction from one sender.
How it works
The website works with Ruby on Rails and I use paypal_adaptive gem for payments with PayPal. The payment flow is quite simple:
The user clicks on Buy button on the website. The client makes AJAX request which handled by payment controller in Ruby on Rails.
In the controller the app makes Pay request to PayPal API using paypal_adaptive gem and receives a PayKey (see the code below).
The server responds to the client with the PayKey and the client uses it in PayPal form to start payment process through PayPal's lightbox (see the code below).
That's it. After that I do not control anything (the payment process goes through PayPal's external webpage).
Additional notes
I'm sure that the data for Pay request is different on the server side in the test scenario listed above.
I've tried different PayPal's dialog options besides PayPal's lightbox: mini-browser and popup. These options doesn't affect on this bug and it is still reproducable.
The client code
<script src="https://www.paypalobjects.com/js/external/dg.js" type="text/javascript"></script>
<form action="https://www.sandbox.paypal.com/webapps/adaptivepayment/flow/pay" class="paypal-hidden-form" target="PPDGFrame">
<button id="paypal-submit"></button>
<input id="type" type="hidden" name="expType" value="light">
<!-- Insert PayKey here and click on the form's submit button using jQuery after server's response. -->
<input id="paypal-key" type="hidden" name="paykey" value="">
</form>
<!-- Paypal -->
<script type="text/javascript" charset="utf-8">
var dgFlow = new PAYPAL.apps.DGFlow({ trigger: "paypal-submit", expType: "light" });
function MyEmbeddedFlow(embeddedFlow) {
this.embeddedPPObj = embeddedFlow;
this.paymentSuccess = function(paymentStatus) {
this.embeddedPPObj.closeFlow();
// More UI code here...
};
this.paymentCanceled = function() {
this.embeddedPPObj.closeFlow();
// More UI code here...
};
}
var myEmbeddedPaymentFlow = new MyEmbeddedFlow(dgFlow);
</script>
The server code
# Make a Pay request to PayPal API.
paypal_payment_thread = Thread.new do
# Some preparation code goes here...
pay_request = PaypalAdaptive::Request.new
process_guid = SecureRandom.uuid
# Construct Pay API request data.
data = {
:returnUrl => "#{PAYPAL_RETURN_URL}?process_guid=#{process_guid}",
:cancelUrl => "#{PAYPAL_CANCEL_URL}?process_guid=#{process_guid}",
:requestEnvelope => {
:errorLanguage => "en_US"
},
:currencyCode => "USD",
:receiverList => {
:receiver => [{
# seller_paypal value is different for two payments.
# But in fact we do the last payment for both payments.
:email => seller_paypal,
:amount => ORDER_SELLER_AMOUNT,
:paymentType => "DIGITALGOODS"
}, {
:email => PAYPAL_MARKETPLACE_EMAIL,
:amount => ORDER_MARKETPLACE_AMOUNT,
:paymentType => "DIGITALGOODS"
}]
},
:actionType => "PAY",
:ipnNotificationUrl => PAYPAL_NOTIFY_URL,
:reverseAllParallelPaymentsOnError => "true",
:trackingId => process_guid
}
# Make a Pay API request.
pay_response = pay_request.pay(data)
if pay_response.success?
# Everything is ok. Update database here...
else
raise Exceptions::PaypalPaymentError
end
end
I've removed some unimportant code just to be clear, how it really works.
Thanks in advance for the help!
Looks like it is by design. I've tried the same test here on the website of one of PayPal's employees and it is reproducible there.
PayPal's support answered me that the problem in using Lightbox. However I've tried Mini-Browser and Popup options as I described in my post without no effect.
Also, PayPal's support answered me that this is by design and adviced me to contact with Technical Support. Maybe it will be useful for someone else.
Hi Michael, Thanks, yes I was able to reproduce it as well. However
it’s important to understand that PayPal is not made for handling 2
payment flows at the same time. If you want to get further on that,
you can contact our Technical Support : https://ppmts.custhelp.com/
They have other tools to debug and may be able to give you a better
understanding of the technical problem.
Finally I've blocked simultaneous payments using a special flag in HTML5 Local Storage and dgFlow.isOpen() method of PAYPAL.apps.DGFlow object to detect PayPal window. On window close I reset this flag using onunload and onbeforeunload events of window.
I close this question. Thanks.