Chapter    14

Charge and E-Mail

In Chapter 12, I showed you how to use the cloud function to create and charge a Stripe Customer. In Chapter 13, I showed you how to use a cloud function to pay with Apple Pay. All three methods call functions of “createStripeCustomer,” “chargeCustomer,” and “chargeToken,” respectively, in a JavaScript file with a name of “main.js” that you have written and hosted on Parse. The three functions take a dictionary input to execute and return either a string if successful or an NSError object if any error occurs. In this chapter, I will show you how you can implement these three JavaScript functions. In addition, you will learn how to use Mailgun to send an order confirmation once Stripe has successfully charged a user’s credit card.

Create and Charge a Customer

To recap, here are the three JavaScript functions you will use in this chapter:

Parse Cloud Code

First, here is some background on Parse Cloud Code. Parse Cloud Code is written in JavaScript and runs in the Parse Cloud rather than running on a mobile device. The Parse Cloud Code you write will work like your own back-end code. Obviously when your Cloud Code is updated, it becomes available to all mobile environments instantly. You don’t have to wait for a new release of your application. This lets you change app behavior on the fly and adds new features faster. Figure 14-1 shows what your cloud function main.js looks like in Parse.

9781484213186_Fig14-01.jpg

Figure 14-1. Cloud Code in Parse

The Parse Command-Line Tool (CLT)

Before you can use the Parse Cloud Code, you will need to install the Parse command-line tool on the computer you use for development. The command-line tool will help you deploy your code to the Parse Cloud. To install this tool, simply run the following command in the terminal:

curl -s https://www.parse.com/downloads/cloud_code/installer.sh | sudo /bin/bash

Once you have Parse CLT installed, you can start to set up a Cloud Code directory. Open the Terminal App, dir, to a directory where you want to put your Cloud Code directory, then type:

>parse configure accountKey –d

The CLT will response with:

> Input your account key or press enter to generate a new one.
Account Key: ${YOUR_ACCOUNT_KEY}

Press Enter, type the following command, and then press Enter again:

> parse new

The CLT will response with:

Would you like to create a new app, or add Cloud Code to an existing app?
Type "(n)ew" or "(e)xisting": e
1:  MyApp
2:  MyOtherApp
Select an App to add to config: 1
Awesome! Now it's time to setup some Cloud Code for the app: "MyApp",
Next we will create a directory to hold your Cloud Code.
Please enter the name to use for this directory,
or hit ENTER to use "MyApp" as the directory name.

Make your choice. Then enter:

> parse deploy

Once you have received a successful message from CLT, you can move to Parse.com, and look at the Cloud Code part in your project dashboard, as shown in Figure 14-1. You will see a simple “Hello World” cloud function.

From now on, you can work on the main.js in your local directory. Once you are ready to deploy, use:

> parse deploy

to deploy to the Parse server.

In the meantime, you can also read any log generated by Cloud Code or every time you make a Cloud Code function call, by tapping the “Logs” on Parse Dashboard, as shown in Figure 14-2.

9781484213186_Fig14-02.jpg

Figure 14-2. Cloud Code logs

Note  To read more about the Parse Command-Line Tool, please visit https://parse.com/apps/quickstart#cloud_code/unix.

Parse Cloud Modules

To make developers’ lives easier, Parse also provides the integration with third-party services and libraries through Cloud Modules. The Cloud Modules work just like JavaScript libraries. For this example, you will use Stripe Cloud Module and Mailgun Cloud Module.

/* Initialize the Stripe and Mailgun Cloud Modules */
var Stripe = require('stripe');
Stripe.initialize('YOUR_STRIPE_TEST_SECRET');

var Mailgun = require('mailgun');
Mailgun.initialize("YOUR_MAILGUN_PROJECT_NAME", "YOUR_MAILGUN_API_KEY");

Create a Stripe Customer

In Chapter 12, you learned how to use the “createStripeCustomer” cloud function to create a Stripe Customer. If you do use this method in your code, you will receive an error that states there is no function named “createStripeCustomer.” So the first cloud function you will implement is “createStripeCustomer.”

[PFCloud callFunctionInBackground:@"createStripeCustomer" withParameters:stripeCustomerDictionary block:^(NSString *customerId, NSError *error) {
}];

First, you will need to include Stripe Cloud Module in your code; also specify the test secret key, as shown here:

var Stripe = require('stripe');
Stripe.initialize('YOUR_TEST_STRIPE_KEY);

Next, define the function name by calling Parse.Cloud.define. Just remember each function requires a unique name.

If you are familiar with JavaScript, in addition to callbacks, every asynchronous method in the Parse JavaScript SDK returns a Promise. With promises, your code can be much cleaner than the nested code you get with callbacks.

Note  To read more about Parse Promise, refer to https://parse.com/docs/js/guide – promises.

Take a close look at the following simple Stripe Customer creation function:

Parse.Cloud.define("createStripeCustomer",function(request,response){
  Parse.Cloud.useMasterKey();

  Parse.Promise.as().then(function(){
    return Stripe.Customers.create({
    description: 'customer for Beauty & Me',
    card:request.params.tokenId,
           email:request.params.customerEmail

    }).then(null, function(error){
      console.log('Creating customer with stripe failed. Error: ' + error);
      return Parse.Promise.error('An error has occurred.');
    });
  }).then(function(customer) {
    response.success(customer.id);
  }, function(error) {
    response.error(error);
  });
});

Basically, you call the Stripe.Customer.create API to create a Stripe Customer. You provide the token you received from the iOS app and the user’s e-mail to create the customer. If the customer is created successfully, you will receive the Stripe Customer object. Since you only need the customer id, return the id in the success response. You also let your iOS app know if there is any error.

Charge Customer

The next cloud function is “charge.” What you received for this function is an order object id and a customer id. Here are the steps you need to follow:

  1. Based on the order object id, find the order; you also need to include the products associated with the order and the customer. You will need this information to generate a receipt.
  2. Charge the customer based on the Stripe Customer id.
  3. Update the order with a new ORDER_COMPLETED status, and then generate a real order id and a big integer number, based on the total orders we have in the system.
  4. Send an e-mail to the customer by calling Mailgun Parse Cloud Module. You might have to compose some e-mail content by mixing html tag and the order’s information.
  5. Once the order confirmation e-mail is sent successfully, send a message back to the iOS app. If any errors occur, return the errors.

Here is the code for the previous five steps:

/* Initialize the Stripe and Mailgun Cloud Modules */
var Stripe = require('stripe');
Stripe.initialize('your_own_stripe_secret);
var Mailgun = require('mailgun');
Mailgun.initialize("your_mailgun_email_account", "your_mailgun_key");

Parse.Cloud.define("chargeCustomer", function(request, response) {
  Parse.Cloud.useMasterKey();
  var order;
  var orderNo;
  Parse.Promise.as().then(function() {
    var orderQuery = new Parse.Query('Order');
    orderQuery.equalTo('objectId', request.params.orderId);
    orderQuery.include("customer");

     orderQuery.include(["items.product"]);
    orderQuery.descending("createdAt");

    return orderQuery.first().then(null, function(error) {
      return Parse.Promise.error('Sorry, this order doesn't exist.');
    });

  }).then(function(result) {
    order = result;
  }).then(function(result) {
    var countQuery = new Parse.Query("Order");
    return countQuery.count().then(null,function(error){
        return Parse.Promise.error('Something wrong.');
    });
  }).then(function(result) {
    orderNo = result;
  }).then(function(order){
    eturn Stripe.Charges.create({
    amount: request.params.amount, // express dollars in cents
    currency: "usd",
    customer:request.params.customerId
    }).then(null, function(error) {
      console.log('Charging with stripe failed. Error: ' + error);
      return Parse.Promise.error('An error has occurred. Your credit card was not charged.');
    });
  }).then(function(purchase) {
    orderNo = 1000000+orderNo;
    order.set('stripePaymentId', purchase.id);
    order.set('orderStatus', 1);  // order made
    order.set('orderNo', orderNo);
    return order.save().then(null, function(error) {
      return Parse.Promise.error('A critical error has occurred with your order. Please ' +
                                 'contact [email protected] at your earliest convinience. ');
    });

  }). then(function(result) {
    var greeting = "Dear ";
    if (request.params.name !== "N/A")
      greeting +=  request.params.name + ", ";
    else
      greeting += request.params.email + ", ";
    var orderId = "Order No. " + orderNo + " ";
    var body = greeting + orderId + "  We have received your order for the following item(s): " +
            request.params.itemDesc + " ";

                 var note = "Note: " + request.params.note +" ";
    body += "Total: $" +  (request.params.amount / 100.00).toFixed(2) + " " + note;

    var thankyou = "Contact us if you have any question! " +
    " Thank you, " + "Beauty 4 You Team";

    body += thankyou;

    // Send the email.
    return Mailgun.sendEmail({
      to: request.params.email,
      bcc: 'CUSTOMER-EMAIL',
      from: 'YOUR-EMAIL',
      subject: '',
      text: body
    }).then(null, function(error) {
      return Parse.Promise.error('Your purchase was successful, but we were not able to ' +
                                 'send you an email. Contact us at YOUR-EMAIL ' +
                                 'you have any questions.');
    });

  }).then(function() {
    // And we're done!
    response.success('Success');
  }, function(error) {
    response.error(error);
  });
});

Charge Token

This function is almost identical to the “chargeCustomer” function. The only difference is that you need to use a card property in the Stripe.Charges.create function:

Stripe.Charges.create({
  amount: request.params.amount, // express dollars in cents
  currency: "usd",
  card:request.params.customerId})

Summary

In this chapter, I showed you how to create a Stripe Customer ID and then use this customer ID to charge a user’s credit card from Parse Cloud Module. I also explained how to use Mailgun to send an order confirmation e-mail to this user.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.135.80