Right, from the previous post we have managed to add the Paypal Smart payment buttons easily. But the buttons, though are functioning, not really do much in terms of providing a way for our customers to pay for our goods or services.
In this post, we will start the journey of making the buttons dynamic, ie. able to charge our customers correctly based on the price of the goods, and once they completed the payment, allow them to access the download link.
If you want to code along with this post, you can do so by checking out from this commit on indiesell repo.
Convert the button to vue component
Remove the second script that we added on the layout template so that it will only look like this:
app/views/layouts/store/application.html.erb
</footer>
<script
id="paypal-sdk-js-src"
src="https://www.paypal.com/sdk/js?client-id=<%= ENV['paypal_client_id'] %>"
data-sdk-integration-source="button-factory"
>
</script>
</body>
Only keep the script source from Paypal, then we add the button container, by replacing the previous button html on the product item partial html
app/views/store/products/_product.html.erb
<!-- TODO: Put the paypal button here -->
<div class="buynow">
<paypal-button
refer="paypal-container-<%= product.id.to_s %>"
/>
</div>
Now if you refresh, the button will disappear, our mission for the next 5 mins is to make that re-appear
- Intro for the vue pack: store.js
This is the current state of the Vue pack that will be responsible to hold all the javascripts needed to easily get our Paypal button to be dynamic.
app/javascript/packs/store.js
import Vue from 'vue/dist/vue.esm'
document.addEventListener('DOMContentLoaded', () => {
var storeList = new Vue({
el: '', // Add the css identifier for the div that will load the paypal button
components: {
// Add paypal button here
}
})
})
This Vue pack is already hooked to our rails HTML template on the layout template for the storefront.
app/views/layouts/store/application.html.erb:13
%= javascript_pack_tag 'store' %>
- Add Paypal JS SDK using yarn
yarn add @paypal/sdk-client
then add to the store.js
import Vue from 'vue/dist/vue.esm'
// add this single line below here to use the Paypal JS SDK we've just installed
import { unpackSDKMeta } from '@paypal/sdk-client';
document.addEventListener('DOMContentLoaded', () => {
- Create the vue component: paypal button
app/javascript/components/paypal_button.vue
<template>
<div :id="refer"></div>
</template>
<script>
export default {
props: {
// This is for giving dynamic container css 'ID' to be called by the Paypal button renderer
refer: {
type: String,
required: true
}
},
data() {
},
mounted: function() {
},
computed: {
},
methods: {
}
}
</script>
The last thing for this step is to hook this newly-created component onto the store.js pack
import Vue from 'vue/dist/vue.esm'
import { unpackSDKMeta } from '@paypal/sdk-client';
// Add this single line below
import PaypalButton from '../components/paypal_button.vue';
document.addEventListener('DOMContentLoaded', () => {
var storeList = new Vue({
el: '#store-list', // Add the css identifier for the div that will load the paypal button
components: {
// Add paypal button here
PaypalButton
}
})
})
Notice that we have just added this line:
components: {
PaypalButton
}
and this line:
el: '#store-list',
but for this line to be working, we need to remember to add this element identifier onto the rails template also
app/views/store/products/index.html.erb
<div
class="section section-demo"
id="store-list" <!-- This is what we add -->
>
<div class="container">
<%= render partial: "product", collection: @products, as: :product %>
</div>
</div>
Two lines, that's it. We will not be adding anymore to this file.
So the setup is ready, all we need to do now is to get the component working.
- Setup the vue component: paypal button
app/javascript/components/paypal_button.vue
// REDACTED //
<script>
export default {
props: {
refer: {
type: String,
required: true
},
// This is where will pass more product attributes to be used in this vue component from the rails html template
},
data() {
return {
// Defaults template for the order JSON payload that will be sent to Paypal
order: {
description: "",
amount: {
currency_code: "",
value: 0
}
}
};
},
mounted: function() {
// IMPORTANT: this method causes the paypal button be loeaded and rendered
this.setLoaded();
},
computed: {
selectorContainer() {
return '#' + this.refer;
}
},
methods: {
setLoaded: function() {
paypal
.Buttons({
createOrder: (data, actions) => {
return actions.order.create({
purchase_units: [
this.order
]
});
},
onApprove: async (data, actions) => {
},
onError: err => {
console.log(err);
}
}).render(this.selectorContainer);
}
}
};
</script>
Up to this point, your component should be ok enough that it will re-appear and working once more.
On the next part, we will have the maximum fun by turning all of these hard work into fruition by tying the checkout button to our backend.
PS: reminder, if you don't want to wait, you can view the full post at this blog post
Top comments (0)