Issues with cart, account created email, and snipcart related scripts

Permalink Browser Info Environment
1. How do you remove the email address in the cart so that it goes back thru the register/login step in case the user changes their email?
See Clipboard02.jpg

2. How to Get new member to receive the
account Created email
using my webhook URL

3. How would I configure implement a webhook at the URL
https://interiorhighlandstrails.us/index.php/snipcartcallback...
in concrete5?????

4. On the "Membership Configuration" page toggling the "Do not login/redirect on order completion" has no effect. The "welcome email with their login details" is not sent ever and a login is not performed.

5. Where am I supposed to insert into concrete5 blocks for example:
Snipcart.api.configure('allowed_countries', ['CA']);

thanks

1 Attachment

Type: Ticket
Status: In Progress
tenmilehigh
View Replies:
mesuva replied on at Permalink Reply
mesuva
Hi there,

I think there's a bit of confusion (perhaps caused by lack of instruction on my part) on how to set this up.

- You don't use Snipcart's registration/login features with this add-on. You configure Snipcart to effectively be a 'guest' checkout. This add-on this creates _Concrete_ logins, and users log in to the site using the normal Concrete login. Then you can control pages and content with normal permissions.

So the answer to 1 is that you set the cart to guest checkout only.

2 - when the webhook from Snipcart hits your site, that's when the account created email gets sent and the new account created.

3 - you go into your Snipcart dashboard (so at Snipcart, not in your Concrete site) and enter the webhook URL on that side of things

4 - this isn't going to work without the webhook working

5 - I'll have to look this up. From memory I thought the countries were controlled via Snipcart's dashboard. Perhaps get the webhook working first then we can look at this.

Just broadly speaking, if you are just selling one thing, and that's a membership, and there's no need for a cart, you might find that Snipcart is overly complex for your needs. Instead you would also be able to do the same membership handling using my 'Payments with Stripe add-on', which is easier to configure and has no monthly cost. If you investigate that and would prefer to use it I can easily refund your Snipcart add-ons.
tenmilehigh replied on at Permalink Reply
tenmilehigh
1. set the cart to guest checkout only but the email address is still hung up in the cart See Clipboard02.jpg and the guest checkout button is never shown???? I have uninstalled and reinstalled snipcart to no avail. Let's get this resolved then we can address 2. - 7.

thanks
mesuva replied on at Permalink Reply 1 Attachment
mesuva
That's working for me now without prompting to login or register. See attached.
Perhaps your browser has a cookie that isn't being unset for snipcart, you may need to test in another browser, or clear cookies.
tenmilehigh replied on at Permalink Reply
tenmilehigh
I cleared the concrete5 cache and the Brave browser cache to no avail.
Seems to work with Edge browser
It seems your addon needs to clear that email when "Allow Guests only" is true!
mesuva replied on at Permalink Reply
mesuva
There are some things my add-on can control, and others it's cant as things that are 100% in Snipcart's domain.

I don't believe I have any control over whether the Snipcart cart holds onto an email or not, that's really going to come down to what cookies Snipcart is going to set.

Try viewing your site using a 'New Private Window' in Brave and see if there's a difference.
tenmilehigh replied on at Permalink Reply
tenmilehigh
Brave requires cookie time range to delete I deleted cookies for all time. So now it works
thanks
tenmilehigh replied on at Permalink Reply
tenmilehigh
2. This is my big problem
I am not using the webhook URL
https://interiorhighlandstrails.us/index.php/snipcartcallback...
but using my own in the same domain
My member never receives the account created email
and my PHP code works perfectly

If I must use
https://interiorhighlandstrails.us/index.php/snipcartcallback...
How do I set that up in concrete5

thanks
mesuva replied on at Permalink Reply
mesuva
It's about following the instructions here:

https://docs.snipcart.com/v3/webhooks/introduction...

You take that webhook URL, go to Snipcart and find Webhook section, and paste and save it in there. That tells Snipcart to tell your site that a transaction has happened.
tenmilehigh replied on at Permalink Reply
tenmilehigh
I do that but I use my own webhook URL

If I must use
https://interiorhighlandstrails.us/index.php/snipcartcallback......
How do I set that up in concrete5 and copy my PHP to it?????
mesuva replied on at Permalink Reply
mesuva
That webhook URL gets effectively created by my add-on.
You shouldn't need to do anything with PHP code, just set it up in Snipcart.

Note that if you visithttps://interiorhighlandstrails.us/index.php/snipcartcallback... now in a browser, you get a 400 error, not the standard concrete not found page.. that shows that it's set up and ready to receive data from Snipcart.

When you say you are using your own webhook URL, what are you looking to do?
tenmilehigh replied on at Permalink Reply
tenmilehigh
I am processing the JSON extracting
user email
phone number
order items

I query the Concrete5 user DB that your addon setup

I insert/update a database with all this data
Which my Android app queries
My website store (only one product is shown but I have 3)
https://interiorhighlandstrails.us/index.php/join...
NOTE: I have not added my App to Google play store yet

thanks
mesuva replied on at Permalink Reply
mesuva
I'm following.

The most appropriate way to handle this would be to respond to the 'event' that the main Snipcart add-on fires when the webhook is accessed.

See a quick summary here:
https://marketplace.concretecms.com/marketplace/addons/ecommerce-wit...

The Snipcart Memberships add-on actually does this itself, it just listens for the event and responds accordingly.
If you see towards the very end of controller.php for the memberships package, you'll see two lines like this:
$listener = Core::make('\Concrete\Package\SnipcartMemberships\Src\Event\Order');
Events::addListener('on_snipcart_callback', array($listener, 'orderPlaced'));


That's where it listens for the event, and calls the orderPlaced function on \Concrete\Package\SnipcartMemberships\Src\Event\Order.

So you could write similar code to also listen to the same event.

Seehttps://documentation.concretecms.org/developers/framework/applicati... for how to do this.

If you're not familiar with writing your own packages, you could even just drop the code into application/bootstrap/app.php.

The code would look like this:
Events::addListener('on_snipcart_callback', function($event) {
    $data = $event->getEventData();
    // $data now contains all the info Snipcart sent to the callback
   // put your own code here.
});
tenmilehigh replied on at Permalink Reply
tenmilehigh
Ok
I will work on this overnight
and get back with you with my results in the AM

Till then
Thanks
tenmilehigh replied on at Permalink Reply
tenmilehigh
I added per your suggestion
Events::addListener('on_snipcart_callback', function($event) {
    $data = $event->getEventData();
    // $data now contains all the info Snipcart sent to the callback
   // my PHP script went here
});


My PHP script works OK except:

Issue #1
Sometimes when I query the Concrete5 user DB that your addon setup
I hit the DB before your work is complete and thus the new member is not in the user DB

Maybe the issue has something to do with the order in which the addListener's are processed???

Any ideas how to fix????

Issue #2
I enter in tabs cart content, billing address, payment method
then click place order in confirm order tab
I noticed the yellow progress bar at top of cart shows briefly
it goes back to payment method tab with no errors shown
If I wait a couple of minutes or longer
then click place order in confirm order tab the order is processed

why and how to fix????

Issue #3
Sometimes the email address is missing from the billing address
in the confirm order tab

Sometimes the payment info is missing from the payment information
in the payment method tab

why and how to fix????

issue #4
Sometime after placing an order a concrete popup says
"Your email address is already linked to an existing user account on this site. If prompted, use your existing credentials to log in."

What does that mean????

thanks
mesuva replied on at Permalink Reply
mesuva
1 - I didn't realise you would be hitting the database, instead of just receiving the callback and using the details directly from that. The event listener in bootstrap.php is going to be loaded early on. I think the most straightforward fix is to package up your listener into a small add-on, as because it'll be installed later, it'll get initialised later.

2 - I'm not familiar with this bug. It's all within Snipcart's cart, so on 'their end' so to speak. When that happens, and you have the developer console open, can you spot any Javascript errors? I just did a very quick test transaction and it went through the checkout steps without issue.

3 - I've also not experienced these things. Again, I'd look for javascript errors for clues.

4 - that's when you use the same email you've used before and a user account already exists. In that case it just modifies the existing user and doesn't create a new account. It might be where you've become a member in the past, and you're buying something new that gives you different site permissions.

If you are already logged in as the user with that email it shouldn't show that message. But if you are not logged in, or logged in as someone else, it shows that message, prompting you to log in as that user.

It won't log you in automatically for an existing account, otherwise people could log in as other users. It'll only log you in automatically when it's a completely new user account.
tenmilehigh replied on at Permalink Reply
tenmilehigh
RE #1
Packages are way to complicated

I am just going to modify your order.php
adding my code at the end of the conditional
if (is_array($data) && isset($data['eventName']) && $data['eventName'] == 'order.completed') {


This way there will be no possibility of timing problems hitting the user DB before your stuff is done.

I will have to add my DB connection to database.php
and of course remember to modify your package if I ever upgrade concrete5

What do you think????

If this works then you might consider implementing a snipcart_memberships webhook.






RE #2
Snipcart support responded with the following
"We apologize for the inconvenience caused due to the rate limit for failed payments. We understand the base error that caused this issue is the fact that the expiration year for the test card is pre-filled to January 2023. We are currently working on a fix and it should be available shortly."
mesuva replied on at Permalink Reply
mesuva
I don't see any issue with putting that code directly in the add-on for now, at least to get it working. I'm unlikely to push up an update for this add-on anytime soon.

It's not _too_ tricky to write a package with a webhook. If you get to that point I can send you a skeleton package for you to drop your code into.

With #2, I actually noticed this myself when I tested it the other day, I had to adjust the expiry date on the test card for it to go through!
tenmilehigh replied on at Permalink Reply
tenmilehigh
RE #1
I like the custom code in orderPlaced($event) rather than a webhook
because a hacker will have to pay to play

code works except for access to my DB
See code

setup:
The subscribed table is empty
index, userID, kmzID columns are ints
index is auto increment, PRIMARY KEY
userID is a key

The $db = \Database::connection('testlogin');
works for other queries

The if($result) conditional always returns true
The INSERT in the conditional if(!$index) is never executed
$index is always empty at all error_logs

Help a fellow out!
Please review my code and see if you can tell me what is not right?????

thanks

// see if already subscribed
                $db = \Database::connection('testlogin');
                $result = $db->query("SELECT * FROM subscribed WHERE userID='$userID' and kmzID='$kmzID'");
                if($result) {
                error_log("ihtsnipcart with result: ", 1, "errorlog@interiorhighlandstrails.us");
                    $row = $result->fetchRow();
                    $index = $row['index'];
                } else {
                error_log("ihtsnipcart NO result: ", 1, "errorlog@interiorhighlandstrails.us");
                    $index = 0;
                }
                /*
                $sql = "SELECT * FROM subscribed WHERE userID=$userID and kmzID=$kmzID";
                $result = mysqli_query($con, $sql);
                $row = mysqli_fetch_array($result);




The fix for issue #2 is now available per snipcart.
but my cart hung in loop again

A new issue #3 for snipcart

At the CONFIRM ORDER tab the phone number entered in the BILLING ADDRESS tab matches
The phone number in the order.completed JSON does not match
See attach JSON array
compare the two [billingAddress] => Array's

If I make purchases by two different customers
then the phone numbers do not match
and the phone numbers in the two [billingAddress] => Array's are reversed
mesuva replied on at Permalink Reply
mesuva
I'm not sure there's much I can suggest to help with #2 and #3, they're very much on the side of Snipcart. It's not things I've seen or heard Snipcart do, I'm wondering if it's still a cookie related thing.

With your code, a couple of quick comments:
- be careful with your queries as you're not escaping the queries or the variables you are directly adding to them. It would be better to use parameterised queries for safety.
See the first example on:https://documentation.concretecms.org/developers/framework/database-...

- $result is going to an object for the query, not true or false based on whether it returned records. You'll need to fetch the result of the query first, then test that:
$result = $db->query("SELECT * FROM subscribed WHERE userID='$userID' and kmzID='$kmzID'");
$row = $result->fetchRow();
if ($row) {   // either false or an array
....


That might be the main issue here.

concrete5 Environment Information

concrete5

Environment Information
# concrete5 Version
Core Version - 8.5.6
Version Installed - 8.5.6
Database Version - 20210622145600

# Database Information
Version: 8.0.32
SQL Mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

# concrete5 Packages
Clear Cache on Admin Login (0.9.1), eCommerce with Snipcart (2.0.3), eCommerce with Snipcart: Memberships (1.1), ExchangeCore reCAPTCHA (1.1.1), Honest Websites Back To Top (1.1.0), Login/Logout Link (1.0), Login Block Pro (2.0.0), Login Dialog (0.9.8), Login Log (1.0.1), Login Page Background (0.9.1), Replica Theme (1.1.0), Responsive Embed (1.0.1)

# concrete5 Overrides
single_pages/snipcartcallback.php

# concrete5 Cache Settings
Block Cache - On
Overrides Cache - Off
Full Page Caching - Off
Full Page Cache Lifetime - Every 6 hours (default setting).

# Server Software
Apache

# Server API
fpm-fcgi

# PHP Version
7.2.34

# PHP Extensions
bcmath, calendar, cgi-fcgi, Core, ctype, curl, date, dom, filter, ftp, gd, gettext, hash, iconv, imap, json, libxml, mbstring, mysqli, mysqlnd, openssl, pcntl, pcre, PDO, pdo_mysql, pdo_sqlite, Phar, posix, Reflection, session, SimpleXML, sockets, SPL, sqlite3, standard, tokenizer, wddx, xml, xmlreader, xmlwriter, xsl, zip, zlib

# PHP Settings
max_execution_time - 30
log_errors_max_len - 1024
max_file_uploads - 20
max_input_nesting_level - 64
max_input_time - 60
max_input_vars - 1000
memory_limit - 64M
post_max_size - 8M
upload_max_filesize - 2M
mysqli.max_links - Unlimited
mysqli.max_persistent - Unlimited
pcre.backtrack_limit - 1000000
pcre.recursion_limit - 100000
session.cache_limiter - <i>no value</i>
session.gc_maxlifetime - 7200

Browser User-Agent String

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36

Hide Post Content

This will replace the post content with the message: "Content has been removed by an Administrator"

Hide Content

Request Refund

You may not request a refund that is not currently owned by you.