Integrate Mollie in Sylius payumbundle - sylius

I'm trying to integrate Mollie in the sylius payumbundle via the omnipay bridge. This is what my configuration looks like:
sylius_payment:
gateways:
mollie: Mollie
payum:
contexts:
mollie:
omnipay_onsite:
type: Mollie
options:
apiKey: test_...
it works fine, however after the payment procedure Mollie redirects back and I get the following error:
The transactionReference parameter is required
Did somebody succeed in integrating sylius with Mollie?

It seems like the OffsiteCaptureAction from the OmnipayBridge is not compatible with the Omnipay/Mollie gateway.
The following part from OffsiteCaptureAction.php is incompatible:
if (false == $details['returnUrl'] && $request->getToken()) {
$details['returnUrl'] = $request->getToken()->getTargetUrl();
}
If you replace the incompatible part with the following lines of code, it works:
if (false == $details['returnUrl'] && $request->getToken()) {
$details['returnUrl'] = $request->getToken()->getAfterUrl();
}
if (false == $details['notifyUrl'] && $request->getToken()) {
$details['notifyUrl'] = $request->getToken()->getTargetUrl();
}
The Mollie gateway uses the notifyUrl as webhook to confirm the payments. This is the most important part of the payment. After it used the webhook/notifyUrl in the background, the customer will be redirected to the returnUrl/AfterUrl. The original piece of code was missing the notifyUrl, and was redirecting the customer to the payment confirmation URL.
It is possible that these changes are not compatible with other gateways. I only use Mollie so it is not a big problem for me.
I have made a fork for the 0.14 branch:
https://github.com/goemaere/OmnipayBridge/blob/0.14/src/Action/OffsiteCaptureAction.php#L43-L49

Related

Microsoft graph api: Some users get a 403 when using my app, others don't, why?

Problem
I get
Microsoft\Graph\Exception\GraphException: [0]: Received 403 for call
to
https://graph.microsoft.com/beta/me/chats/[id]#unq.gbl.spaces/members
I fail to understand why.
Research
permissions in Azure
how the exception appears in my queue
Additional information
Just to be clear: this same request with other users of our company is working, so it's not something that always fails. It might be worth noting that the permissions starting with Chat are from the beta version of the graph api. Also retrieving info about the user (ownUser getGivenName) is working for all users.
App scopes
The scopes defined in the application are:
openid
profile
offline_access
user.read
mailboxsettings.read
calendars.readwrite
Chat.ReadBasic
Chat.Read
Chat.ReadWrite
Response of the server
The response completely:
{
"error": {
"code": "Forbidden",
"message": "Forbidden",
"innerError": {
"date": "2021-05-04T12:05:41",
"request-id": "xxxxxxx-f7ea-4912-a23b-676002d0912d",
"client-request-id": "xxxxxxx-f7ea-4912-a23b-676002d0912d"
}
}
}
The response headers also don't reveal anything:
Also tried
I also tried re-visiting https://login.microsoftonline.com/common/adminconsent?client_id=[id] and give my (admin) consent, however this doesn't change anything.
JWT token
Also I decoded both a working users jwt token and a non-working one and they have the same scp (scopes) configured. Here is the diff
used endpoints
/me/chats
/me
/me/chats/$chatId/messages
/me/chats/$chatId/members
Just some observations and workarounds to help out others who come on this post through google:
Only the /me/chats/$chatId/members fails, without an apparant reason. It might be a mistake in in the beta implementation. Maybe it's better to use the $expand argument to see them to mitigate this problem.
for another subgroup of users retrieving all the chats with the endpoint /me/chats with the php sdk also fails with the recommended code
public function listChats(): array
{
$graph = $this->getGraph();
$chats = [];
$response = $graph->setApiVersion("beta")
->createCollectionRequest("GET", "/me/chats")
->setReturnType(Chat::class);
while (!$response->isEnd()) {
$chats = array_merge($chats, $response->getPage());
}
return $chats;
}
because the while loop never stops. #odata.nextLink is always present in the response for these users. Probably also a bug as by design the sdk checks if it's present.
$maxRequests = 10;
while (!$response->isEnd() && $maxRequests > 0) {
$chats = array_merge($chats, $response->getPage());
$maxRequests--;
}

React native in app purchase not giving latest receipt

I am using react-native-iap package. I am trying to get latest subscription and check its validity
await RNIap.validateReceiptIos(receiptBody, true).then((receipt) => {
try {
const renewalHistory = receipt.latest_receipt_info
const expiration = renewalHistory[0].expires_date_ms
expired = Date.now() > expiration
productId = renewalHistory[0].product_id
} catch (error) {}
})
I am multiple auto renewal subscription in a single group. I subscribe to one and I execute code above give me the subscribed product and i tag it as subscribed. First try works fine. Now after that I subscribe again another package and run code above gives me the previous subscription not the current that i subscribed. Sometime second steps also works fine but issue came in third step. Reason I found is I am not getting latest subscribed receipt info in latest_receipt_info above.
Have a look to this tutoriel on YouTube it may help you : https://youtu.be/4JLHRV2kiCU
Also, here is what he said in the comment section :
where I write renewalHistory[renewalHistory.length - 1], this works fine in the test environment. HOWEVER, it seems that when the app is published, this doesn't work and you should instead do renewalHistory[0].
I fixed this in my app by first trying to validate using the production URL, using renewalHistory[0].
If you receive a 21007 status code after trying to validate with the production URL, you validate using the test URL using renewalHistory[renewalHistory.length - 1]

Registering a Shopify Webhook via the ShopifyAPI gem

This call correctly returns an empty array:
hooks = ShopifyAPI::Session.temp(s.myshopify_domain, s.shopify_access_token) do
ShopifyAPI::Webhook.find :all
end
While this call always returns a 403:
hook = ShopifyAPI::Session.temp(s.myshopify_domain, s.shopify_access_token) do
ShopifyAPI::Webhook.create(
format: 'json',
topic: 'orders/fulfilled',
address: "http://www.something.fr/api/webhooks?store_id=#{s.id }&store_check=#{ s.checksum }"
)
end
I've tried pretty much all solutions offered over various websites, each time with a failure.
What am I missing here?
The whole code block given in original post is correct.
It was in fact a rights problem, the customer who provided us with the API tokens didn't enable webhook creation rights on the Shopify configuration.
It might seem like nothing, but it is critical that you check that with whoever gave you credentials!
Try this
hook = ShopifyAPI::Session.temp(s.myshopify_domain, s.shopify_access_token) do
ShopifyAPI::Webhook.new(
format: 'json',
topic: 'orders/fulfilled',
address: "http://www.something.fr/api/webhooks?store_id=#{s.id }&store_check=#{ s.checksum }"
)
end
Possible duplicate: Error Creating Shopify Webhook through the API

Redirect to custompage.php instead of viewinvoice.php if payment fails in WHMCS Vs 6.2.0

I wish to redirect to a custom page following the failure in payment as returned by payment gateway.
To this end, I am using the ShoppingCartCheckoutCompletePage hook to check this using the variable $vars['ispaid'].
When payment is successful, $vars['ispaid'] is true and the redirect to the thankyou page works.
add_hook('ShoppingCartCheckoutCompletePage', 1, function ($vars)
{
# Will be true if the order has been paid
if($vars['ispaid'] == true)
{
#redirect to thank you page
header('location:'.thankYouPage);
die;
}
else
{
header('location:'.transactionFailedPage);
die;
}
}
However the else statement is not executing when payment obviously fails,
rather the viewinvoice.php page is loaded and payment status set to 'unpaid'
Am I missing something?
How can I redirect to the transaction failed page?
Thanks.
WHMCS doesn't provide an intuitive way to get to where you are wanting to go, that's for sure. You may need to add a file to execute in the hooks directory to run without a hook - any php you add into the hooks directory gets executed as soon as the system starts up and security checks are done. So this means you can see if you are a) on the viewinvoice.php file, b) if there is an error message indicating a failed payment and c) redirect from there if these are true.
The ShoppingCartCheckoutCompletePage I believe is only called after the order is complete and payment is made, that's what I recall though, and again, it's not intuitive.
Hope that is of help.

Is there a way to stop Google Analytics counting development work as hits?

I have added the JavaScript that I need to the bottom of my pages so that I can make use of Google Analytics. Only problem is that I am sure that it is counting all my development work as hits. Seeing as I probably see some of those pages a hundred times a day it will really skew my readings. Is there a way to turn it off from a particular IP address or is this something that should be built into my build process so it only gets added when I build for deployment?
I like the simple approach of using javascript. It works anywhere.
<script type="text/javascript">
if (document.location.hostname.search("myproductiondomainname.com") !== -1) {
//google analytics code goes here
}
</script>
Yeah, you go into Analytics Settings, edit your site, and +Add Filter to define a filter that excludes your IP address.
Past data is not regenerated with filters applied, so you'll only have the benefit of them moving forward.
It's 2014 and I'm still unsatisfied with all existing solutions...
IP filters require a static IP address. What if I'm working from home or from a coffee shop?
Checking host name eliminates hits from a dev environment, but what if I'm debugging the live site?
Editing server configurations is annoying/advanced and multiple domains are complicated.
Opt-Out extensions either block hits on all websites or none at all depending on who you ask.
So, I created my own Browser Extension...
https://chrome.google.com/webstore/detail/lknhpplgahpbindnnocglcjonpahfikn
It follows me wherever I go
It works on a dev environment and on live/public domains
It only affects me and the sites that I'm developing
It turns on/off with one click
It's easy to verify that it is truly not sending any data to analytics
It works by keeping a "developer cookie" set on your machine at all times just for the domains that you choose. You then simply check for this cookie in your script before sending any data to Analytics. You customize your own unique NAME and VALUE for the cookies in the extension's settings. This can easily be used by a team of people, so developers, content creators, proofreaders, and anyone else in your organization can all view pages without inflating the statistics.
Examples of how to put the code into your pages...
JavaScript
if (window.location.host==="mydomain.com" || window.location.host==="www.mydomain.com") {
if (document.cookie.indexOf("COOKIENAME=COOKIEVALUE") === -1) {
// Insert Analytics Code Here
}
}
PHP
if ($_SERVER['HTTP_HOST']==="mydomain.com" || $_SERVER['HTTP_HOST']==="www.mydomain.com") {
if (#$_COOKIE["COOKIENAME"] !== "COOKIEVALUE") {
// Insert Analytics Code Here
}
}
Verifying that the HOST name equals the domain of your live site ("mydomain.com") ensures that the analytics data will never be sent by ANY visitor while viewing from a test domain such as "localhost" or "beta.mydomain.com". In the examples above, "www.mydomain.com" and "mydomain.com" are the two valid domains where we DO want visits to be recorded.
The live site sends data to analytics as expected UNLESS a developer cookie is found with matching values. If it sees that unique cookie set on your device, then your visit will not count towards your totals in Google Analytics or whatever other analytics tool you prefer to use.
Feel free to share my solution and use my extension to keep those cookies set.
If you're not using static IP, setting IP filters on GA can't help you.
Set an environment variable and conditionally display it. Take the following Ruby on Rails code, for instance:
<% unless RAILS_ENV == "development" %>
<!-- your GA code -->
<% end %>
You can extend this behavior every language/framework you use on any operating system. On PHP, you can use the getenv function. Check it out the Wikipedia page on Environment Variables to know how to proceed on your system.
You can use this code
<script>
var host = window.location.hostname;
if(host != "localhost")
{
// your google analytic code here
}
</script>
The solution is to use Google Tag Manager (GTM) to handle your Google Analytics. This will allow you to only fire Google Analytics on your production domain without having to write any conditionals in your site's code. Here's how to do it:
In GTM, set a Trigger that only fires when the Page Hostname contains your production domain.
Then set a Tag for Universal Analytics and make its Trigger the one you just created.
We setup a 2nd google analytics tracking code for development and QA work -- actually comes in handy when you want to test your analytics integration, also ensures one doesn't have bleedover into production stats.
If You are behind NAT or You can't for other reason give Your IP to Google Analytics, then the simplest method is to set the google analytics domain to localhost (127.0.0.1), from now when You open Your browser, all request to Google Analytics will be directed to Your working station, without knowledge of Google Analytics.
To disable localhost hits, just create a filter to exclude localhost. Go to Admin -> Property -> View Settings to do so. Check the following screenshot for some help.
To disable production URL hits for yourself if you visit using a non-static IP, you can use a Chrome extension like Developer Cookie to skip running the Google Analytics code if it's you.
I personally don't do this since I use an Ad Blocker which already blocks Google Analytics on my browser.
There are a few Chrome extensions that do this for you, like https://chrome.google.com/webstore/detail/fadgflmigmogfionelcpalhohefbnehm
Very convenient if your IP address is not static.
Add this line before your Google Analytics async code runs to disable tracking for that web property ID:
window['ga-disable-UA-XXXXXX-Y'] = true;
UA-XXXXXX-Y corresponds to the web property ID on which you would like to disable tracking.
From: https://developers.google.com/analytics/devguides/collection/gajs/
Use a custom metric to filter all this traffic.
When you init GA in your app, set a custom flag to track developres:
// In your header, after the GA code is injected
if( <your_code_to_check_if_is_dev> ) {
ga('set', 'is_developer', 1 );
}
Then add a filter in your GA Account to remove these results.
Admin > Account > All Filters > Add Filter > User Defined
For Google Analytics 4 (GA4), you can create a rule to define IP addresses whose traffic should be marked as internal.
Define Internal Traffic
Path: Admin > Property > Data Streams > select your stream > More Tagging Settings > Define internal traffic
Define a rule to match one or more IPs that represent your internal traffic.
GA4 Data Filters
Path: Admin > Property > Data Settings > Data Filters
You will find the default filter "Internal Traffic" set to "Testing" mode.
Change to "Active" to enable the filter.
I use Ad Blocker for Firefox, it can specifically block the Google analytics tracking script. Since firefox is my primary development browser it works great until i need to test my work in other browsers.
Probably not helpful to you, but I solved this problem by writing a custom ASP.NET server control that injects the required JavaScript. I then added the live URL to web.config and then only made the control visible when the host name matched the live URL in web.config.
If you have a react application and you have ejected the app(this could work for CRA as well). You can make use of the below code snippet in the index.html page.
<script type="text/javascript">
if("%NODE_ENV%"==="production"){
//your analytics code
}
Like people are mentioning you can either host the google-analytics.com domain locally or setup a function to see if you are working in your development network.
Keep in mind if http://www.google-analytics.com/ga.js does not load and your using onclick javascript functions to help track clicks on page elements.
IE:
onclick="javascript:pageTracker._trackPageview('/made/up/folder/reference');
Your going to have JavaScript errors that will stop jQuery or other robust JavaScript functions from functioning.
Just as an additional option for this, I have a development server with lots of different sites and developers. This meant that I wasn't particularly happy with the 3 main options
hosts file- problematic with lots of developers and open to human error
if/else development block on every site etc
configuration on GA website - some clients have their own GA accounts; would have to be completed on every site with the potential to be forgotten/overlooked
Rather than implementing the various options in the other answers here I approached the problem in the following way. In the global httpd.conf (rather than a site specific one) I used the apache module mod_substitute to simulate the effect the hosts file fix in another answer has, but for every development site, and every developer automatically.
Enable the module
CentOS: Open /etc/conf/httpd.conf and add the following line
LoadModule substitute_module modules/mod_substitute.so
Ubuntu/Debian: Run the following command
sudo a2enmod substitute
Once you've got the module enabled add the following lines to your httpd global config file
CentOS: /etc/conf/httpd.conf
Ubuntu/Debian: /etc/apache2/httpd.conf
# Break Google Analytics
AddOutputFilterByType SUBSTITUTE text/html
Substitute "s|.google-analytics.com|.127.0.0.1|n"
Then restart apache
CentOS: service httpd restart
Ubuntu/Debian: /etc/init.d/apache2 restart
What this does is replace all text matching .google-analytics.com with .127.0.0.1 when apache serves the page so your page renders with analytics code similar to the below example
var _gaq = _gaq || [];
_gaq.push(['_setAccount', '']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.127.0.0.1/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
I know this post is super old, but none of the solutions met my needs. Not only did I want to remove dev work from GA (and FB), but I also wanted to have some folks within the company not be counted in GA and FB. So I wanted a relatively easy method for those folks to exclude themselves from analytics without a plugin, or ruling out a domain ip (as folks with laptops wander).
I created a webpage that users can go to and click a link to opt out of the GA and FB tracking. It places a cookie for the site. Then I check that cookie to determine if we should send data to GA and FB.
I originally set this up on a site for called Dahlia, which is a boutique maker of items for Greek Orthodox Weddings and Baptisms.
Here's the code:
I put the following code in the header for all web pages:
<script>
//put in your google analytics tracking id below:
var gaProperty = 'UA-XXXXXXXX-X';
// Disable tracking if the opt-out cookie exists.
var disableStr = 'ga-disable-' + gaProperty;
if (document.cookie.indexOf(disableStr + '=true') > -1) {
window[disableStr] = true;
window['ga-disable-UA-7870337-1'] = true; //This disables the tracking on Weebly too.
} else {
//put in your facebook tracking id below:
fbq('init', 'YYYYYYYYYYYYYYY');
fbq('track', 'PageView');
}
</script>
Be sure to add your GA and FB tracking IDs in the spaces provided. This was originally written for a Weebly (shopping CMS) site. So if you are not on Weebly you can remove the line that mentions weebly.
Then I created a new webpage called "do-not-track" with the following code in the header:
<script>
//put in your own google analytics tracking id below:
var gaProperty = 'UA-XXXXXXXX-X';
var disableStr = 'ga-disable-' + gaProperty;
// Opt-out function
function gaOptout() {
document.cookie = disableStr + '=true; expires=Thu, 31 Dec 2099 23:59:59 UTC; path=/';
window[disableStr] = true;
gaOptoutCheck();
}
// Check Opt-out function
function gaOptoutCheck() {
var name = "ga-disable-"+gaProperty+"=";
var ca = document.cookie.split(';');
var found = "false";
for(var i=0; i<ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1);
if (c.indexOf(name) == 0) found = "true";
}
if (found == "true") alert("Cookie is properly installed");
else alert("COOKIE NOT FOUND");
}
</script>
And the following code in the body:
Click here to opt-out of Google and Facebook Analytics
<br><br>
Please visit this page on every computer, laptop, phone, tablet, etc. that you use;
and for all browser you use on each of those devices.
<br><br>
If you ever remove cookies from browser, you will need to repeat this process for that browser.
<br><br><br>
<a href="javascript:gaOptoutCheck()">
Click to check if cookie is set</a>
<br><br>
Here is my full writeup for the Weebly site
Hope this helps somebody!
get the request host variable.
So wrap an if statement around the analytics javascript like this (Ruby-esque pseudocode):
<body>
<shtuff>dfsfsdf</shtuff>
if not (request.host == 'localhost')
#analytics code here
elsif (request.host == the server's ip/domain)
#analytics code here
else
#do nothing
end
</body>
I have a PHP variable set for my local development that gives me a terminal for providing data/feedback etc when I'm working on stuff.
I use XAMPP so that has an env variable for tmp which is the following:
$isLocal = (getenv("tmp") == '\xampp\tmp') ? true : false;
This doesn't exist on my production server because xampp is not being used
if($isLocal){
// do something, eg. load my terminal
}
... Specific to this question:
<?php if(!$isLocal){ ?>
<!-- Insert Google Analytics Script Here -->
<?php } // end google analytics local check ?>
Today, whilst on a different computer than my own, I noticed μBlock Origin for Chrome was blocking Google AdSense by default. After some Googling, I found this article. It notes also μBlock Origin Firefox, μ Adblock for Firefox and Ad Muncher for Windows block AdSense by default. Most other options are listed as being configurable to block AdSense.
This seems to work and is useful because my IP is often dynamic, so the Chrome extension can follow me around as long as I am logged in to Chrome.
Unfortunatelly, it doesn't seem to be possible to exclude localhost from the reporting when using App + Web Properties type of setup:
Displaying Filters for web-only Properties only. Filters can't be applied to App + Web Properties.
For the nextjs web application, especially ones which are using static generation or SSR this would work:
In your document.tsx
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
. . . . .
<body>
<Main />
<NextScript />
{process.env.NODE_ENV === 'production' ? injectAnalytics() : ''}
</body>
</Html>
);
}
}
where injectAnalytics is a function which returns your GA code, for instance:
function injectAnalytics(): React.ReactFragment {
return <>
{/* Global Site Tag (gtag.js) - Google Analytics */}
<script
async
src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
/>
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
window.gtag = gtag;
gtag('js', new Date());
gtag('config', '${GA_TRACKING_ID}', {
page_path: window.location.pathname,
});
`,
}}
/>
</>
}
I am using this code to disable google analytics in rails 6 in production.
When admin login I set is_developer cookie to disable google analytics for 1 year.
If admin logout, I do not delete is_developer cookie. So,google analytics will be disabled after admin logout.
You can comment all console.log after testing.
<% if Rails.env.production? %>
<% ga_tracking_id = 'G-36......Y6' %>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=<%= ga_tracking_id %>"></script>
<% if user_signed_in? && current_user.admin? %>
<script>
if(document.cookie.indexOf('is_developer') > -1) {
console.log('gtag:- is_developer cookie already set');
} else {
document.cookie = `is_developer=1; expires=${new Date(new Date().getTime()+1000*60*60*24*365).toGMTString()}; path=/`;
console.log('gtag:- is_developer cookie set for 1 year');
}
</script>
<% end %>
<script>
if(document.cookie.indexOf('is_developer') > -1) {
console.log('gtag:- disabled for developer');
} else {
console.log('gtag:- enabled');
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '<%= ga_tracking_id %>');
}
</script>
<% end %>
If you have any suggestions, comment below.