Created
November 15, 2019 21:56
-
-
Save jreviews/3113bf38e69d13dedd581d788d9495e2 to your computer and use it in GitHub Desktop.
How to do e-commerce with JReviews and Stripe https://www.jreviews.com/blog/ecommerce-with-jreviews-and-stripe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
defined('MVC_FRAMEWORK') or die; | |
require dirname(dirname(__FILE__)).DS.'filters/stripe_config.php'; | |
DeveloperController::macro('stripe_checkout', function() use ($stripe_config) | |
{ | |
$config = $stripe_config; | |
$client = new \GuzzleHttp\Client(); | |
if ( !($listingId = $this->params['id']) ) | |
{ | |
return $this->reponse->json()->not_found(); | |
} | |
S2App::import('Component','listings_repository','jreviews'); | |
$listingRepo = (new ListingsRepositoryComponent())->startup($this); | |
$listing = $listingRepo->whereListingId($listingId)->one(); | |
$price = S2Array::get($listing,'Field.pairs.'.$config['price_field'].'.value.0',null); | |
if ( !$price ) | |
{ | |
return $this->response->json()->not_found(); | |
} | |
$image = S2Array::get($listing,'MainMedia.media_info.image.url'); | |
$data = [ | |
'payment_method_types' => $config['payment_method_types'], | |
'line_items' => [ | |
[ | |
'name' => $listing['Listing']['title'], | |
'amount' => $price * 100, // Stripe works in cents | |
'currency' => $config['currency'], | |
'quantity' => 1, | |
'images' => $image ? [$image] : [], | |
] | |
], | |
'payment_intent_data' => [ | |
'description' => $config['statement_descriptor'], // Statement Descriptor | |
'metadata' => [ | |
'listing_id' => $listing['Listing']['listing_id'], | |
'title' => $listing['Listing']['title'], | |
'user_id' => $this->auth->id, | |
'name' => $this->auth->name | |
] | |
], | |
// ,'customer' => '' // This needs to be a Stripe customer object | |
'client_reference_id' => $this->auth->id, | |
'success_url' => $config['success_url'], | |
'cancel_url' => $config['cancel_url'] ?? cmsFramework::makeAbsUrl(cmsFramework::getCurrentUrl()), | |
]; | |
$response = $client->post('https://api.stripe.com/v1/checkout/sessions', [ | |
'auth' => [$config['stripe_sk'],''], | |
'form_params' => $data, | |
'http_errors' => false, | |
]); | |
if ( $response->getStatusCode() == 200 ) | |
{ | |
$checkoutSession = json_decode((string) $response->getBody(),true); | |
return $this->response->json()->array(['success'=>true,'session_id'=>$checkoutSession['id']]); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
defined('MVC_FRAMEWORK') or die; | |
require 'stripe_checkout.php'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
defined('MVC_FRAMEWORK') or die; | |
require_once 'stripe_config.php'; | |
$jreviewsCheckout = new JReviewsCheckout($stripe_config); | |
Clickfwd\Hook\Filter::add('post_get_listing_detailpage_query', [$jreviewsCheckout, 'store_add_buy_button'], 10); | |
Clickfwd\Hook\Filter::add('before_theme_render_viewvars_com_content_com_content_view', [$jreviewsCheckout, 'stripe_bootstrap'], 10); | |
class JReviewsCheckout { | |
protected $config; | |
public function __construct($config) | |
{ | |
$this->config = $config; | |
} | |
public function store_add_buy_button($listing, $params) | |
{ | |
// Only process if the listing has a price set | |
if( !S2Array::get($listing,'Field.pairs.'.$this->config['price_field'].'.value.0',null) ) | |
{ | |
return $listing; | |
} | |
$auth = S2Object::make('auth'); | |
$field = ['jr_store_buy'=>[ | |
'field_id' => 99999, | |
'group_id' => 'store', | |
'name' => 'jr_store_buy', | |
'type' => 'banner', | |
'title' => '', | |
'value' => ['banner'], | |
'text' => ['banner'], | |
// We pass the listing ID as a data attribute so it can be sent to the server | |
// where we read the price and generate the Stripe checkout session ID | |
'description' => sprintf('%s', $this->config['buy_button_css'], $listing['Listing']['listing_id'], $this->config['buy_button_text']), | |
'image' => [], | |
'properties' => [ | |
'show_title' => 0, | |
'location' => 'content', | |
'contentview' => 1, | |
'listview' => 0, | |
'listsort' => 0, | |
'search' => 0, | |
'access' => $auth->getAllAccessGroupId(), | |
'access_view' => $auth->getAllAccessGroupId(), | |
'output_format' => '{fieldtext}', | |
], | |
] | |
]; | |
$group = ['store'=>[ | |
'Group'=>[ | |
'group_id'=> 'store', | |
'title'=> 'Store', | |
'name'=> 'store', | |
'show_title'=>0 | |
], | |
'Fields'=>$field | |
]]; | |
if ( !empty($listing['Field']['groups']) ) | |
{ | |
$listing['Field']['groups'] = array_merge($group,$listing['Field']['groups']); | |
} | |
if ( !empty($listing['Field']['pairs']) ) | |
{ | |
$listing['Field']['pairs'] = array_merge($field,$listing['Field']['pairs']); | |
} | |
return $listing; | |
} | |
public function stripe_bootstrap($viewVars, $params) | |
{ | |
// Only process if the listing has a price set | |
if( !S2Array::get($viewVars,'listing.Field.pairs.'.$this->config['price_field'].'.value.0',null) ) | |
{ | |
return $viewVars; | |
} | |
cmsFramework::addScript('https://js.stripe.com/v3/', 'stripe-api'); | |
$asset_manager = S2Object::make('asset_manager'); | |
// The script below makes a request to DeveloperController::stripe_checkout, which is a custom | |
// method that we will add using a controller macro. We send the listing ID with this request. | |
$script = " | |
var stripe = Stripe('".$this->config['stripe_pk']."'); | |
jreviews.stripeStore = { | |
bootstrap: function() { | |
jQuery('body').on('click','.jr-stripe-buy',function(e) { | |
e.preventDefault(); | |
jreviews.dispatch({ | |
method:'post', | |
type:'json', | |
controller:'developer', | |
action:'stripe_checkout', | |
data:{ id: jQuery(this).data('id') } | |
}).then( res => { | |
if ( res && res.success ) { | |
stripe.redirectToCheckout({ sessionId: res.session_id }).then(handleResult); | |
} | |
}) | |
}); | |
var handleResult = function(result) { | |
if (result.error) { | |
console.log(result.error); | |
} | |
}; | |
} | |
}; | |
if ( typeof head == 'function' ) { | |
head.ready(function() { | |
jreviews.addOnload('stripe-bootstrap',jreviews.stripeStore.bootstrap); | |
}); | |
} else { | |
jreviews.addOnload('stripe-bootstrap',jreviews.stripeStore.bootstrap); | |
} | |
"; | |
$asset_manager->addScript($script,'jreviews-stripe-checkout','addon'); | |
return $viewVars; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
defined('MVC_FRAMEWORK') or die; | |
$stripe_config = [ | |
// Name of custom field you want to use for price information | |
'price_field' => 'jr_productprice', | |
// Get the private and secret keys from your Stripe dashboard and add them below. | |
'stripe_pk' => 'pk_live_........................', | |
'stripe_sk' => 'sk_live_........................', | |
// This appears in the client's credit card statement for the transaction | |
'statement_descriptor' => 'Statement Descriptor', | |
'currency' => 'usd', | |
// Include 'ideal' in the array below if you enable iDEAL payments in the Stripe dashboard, | |
// and set the currency to EUR which is required for iDEAL payments | |
'payment_method_types' => ['card'], | |
// Set 'billing_address_collection' to 'required' to always collect customer billing info | |
'billing_address_collection' => 'auto', | |
// Can use stripe template var {CHECKOUT_SESSION_ID} | |
// Create a success page on your site and update the URL below | |
'success_url' => 'https://your-domain/success-page', | |
// Create a cancel page on your site and update the URL below. Leave null to go back to referrer page. | |
'cancel_url' => null, | |
'buy_button_text' => 'Buy now', | |
'buy_button_css' => 'jrButton jrBlue', | |
]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To use these files, follow the instructions in the How to do e-commerce with JReviews and Stripe blog post.