Ejemplo de uso de la libreria de pagos de Paypal para Android

by Francho Joven

29 Dec 2010

. Comments

paypal_device
En uno de los proyectos Android del trabajo tenemos que incorporar pagos a través de Paypal.

La primera idea que hemos tenido ha sido intentar usar un componente webview que cargara el formulario Paypal, sin embargo la web no se mostraba todo lo bien que era de esperar.

Investigando alternativas, he visto que había una librería oficial de PayPal nativa para Android que facilita mucho las cosas, y con muy pocas lineas de código se puede crear un pago a través de este sistema.

El siguiente código es un ejemplo sencillo de uso, basado en el ejemplo que trae el SDK de Paypal. Le he limpiado el código dejando un solo ejemplo de uso (el pago sencillo), y lo he reconvertido para que use una tarea asíncrona en vez de un handler (no se porque, pero me resulta mas sencillo de usar).

La idea es que la librería debe inicializarse en segundo plano, ya que conectacon los servidores de Paypal. Una vez todo está ok, creamos un boton de pago, que al ser pulsado lanza una Activity que incorpora la propia librería pasando los datos del pedido, y esperamos su respuesta.

Para configurar el entorno de pruebas (sandbox) deberemos seguir las instrucciones de este manual.

<br />
package com.paypal.android.mplexample;</p>
<p>import java.math.BigDecimal;</p>
<p>import android.app.Activity;<br />
import android.content.Context;<br />
import android.content.Intent;<br />
import android.os.AsyncTask;<br />
import android.os.Bundle;<br />
import android.view.View;<br />
import android.view.ViewGroup;<br />
import android.view.View.OnClickListener;<br />
import android.widget.Toast;</p>
<p>import com.paypal.android.MEP.CheckoutButton;<br />
import com.paypal.android.MEP.PayPal;<br />
import com.paypal.android.MEP.PayPalActivity;<br />
import com.paypal.android.MEP.PayPalInvoiceData;<br />
import com.paypal.android.MEP.PayPalInvoiceItem;<br />
import com.paypal.android.MEP.PayPalPayment;</p>
<p>/**<br />
 * Simple use example for the Paypal library<br />
 *<br />
 * @author http://francho.org<br />
 *<br />
 *         Based on the example provided by Paypal Android SDK<br />
 *         https://www.x.com/community/ppx/sdks<br />
 *<br />
 */<br />
public class CheckOutActivity extends Activity implements OnClickListener {</p>
<p>	private static final int REQUEST_PAY = 0;</p>
<p>	@Override<br />
	protected void onCreate(Bundle savedInstanceState) {<br />
		super.onCreate(savedInstanceState);</p>
<p>		setContentView(R.layout.main);</p>
<p>		InitPayPalLibraryAsyncTask task = new InitPayPalLibraryAsyncTask(this,<br />
				this);</p>
<p>		task.execute();<br />
	}</p>
<p>	public void onClick(View v) {<br />
		PayPalPayment payment = getExampleSimplePayment();<br />
		// Use checkout to create our Intent.<br />
		Intent checkoutIntent = PayPal.getInstance().checkout(payment, this,<br />
				new ResultDelegate());<br />
		// Use the android's startActivityForResult() and pass in our Intent.<br />
		// This will start the library.<br />
		startActivityForResult(checkoutIntent, REQUEST_PAY);<br />
	}</p>
<p>	public void onActivityResult(int requestCode, int resultCode, Intent data) {<br />
		if (requestCode != REQUEST_PAY) {<br />
			return;<br />
		}</p>
<p>		/**<br />
		 * If you choose not to implement the PayPalResultDelegate, then you<br />
		 * will receive the transaction results here. Below is a section of code<br />
		 * that is commented out. This is an example of how to get result<br />
		 * information for the transaction. The resultCode will tell you how the<br />
		 * transaction ended and other information can be pulled from the Intent<br />
		 * using getStringExtra.<br />
		 */<br />
		switch (resultCode) {<br />
		case Activity.RESULT_OK:<br />
			/*<br />
			 * TODO<br />
			 */<br />
			break;<br />
		case Activity.RESULT_CANCELED:<br />
			/*<br />
			 * TODO<br />
			 */<br />
			break;<br />
		case PayPalActivity.RESULT_FAILURE:<br />
			/*<br />
			 * TODO<br />
			 *<br />
			 * resultInfo =<br />
			 * data.getStringExtra(PayPalActivity.EXTRA_ERROR_MESSAGE);<br />
			 * resultExtra = &quot;Error ID: &quot; +<br />
			 * data.getStringExtra(PayPalActivity.EXTRA_ERROR_ID);<br />
			 */<br />
			break;<br />
		}<br />
	}</p>
<p>	private PayPalPayment getExampleSimplePayment() {<br />
		// Create a basic PayPalPayment.<br />
		PayPalPayment payment = new PayPalPayment();<br />
		// Sets the currency type for this payment.<br />
		payment.setCurrencyType(&quot;EUR&quot;);<br />
		// Sets the recipient for the payment. This can also be a phone number.<br />
		payment.setRecipient(&quot;example-merchant-1@paypal.com&quot;);<br />
		// Sets the amount of the payment, not including tax and shipping<br />
		// amounts.<br />
		payment.setSubtotal(new BigDecimal(&quot;8.25&quot;));<br />
		// Sets the payment type. This can be PAYMENT_TYPE_GOODS,<br />
		// PAYMENT_TYPE_SERVICE, PAYMENT_TYPE_PERSONAL, or PAYMENT_TYPE_NONE.<br />
		payment.setPaymentType(PayPal.PAYMENT_TYPE_SERVICE);</p>
<p>		// PayPalInvoiceData can contain tax and shipping amounts. It also<br />
		// contains an ArrayList of PayPalInvoiceItem which can<br />
		// be filled out. These are not required for any transaction.<br />
		PayPalInvoiceData invoice = new PayPalInvoiceData();<br />
		// Sets the tax amount.<br />
		invoice.setTax(new BigDecimal(&quot;1.25&quot;));<br />
		// Sets the shipping amount.<br />
		invoice.setShipping(new BigDecimal(&quot;4.50&quot;));</p>
<p>		// PayPalInvoiceItem has several parameters available to it. None of<br />
		// these parameters is required.<br />
		PayPalInvoiceItem item1 = new PayPalInvoiceItem();<br />
		// Sets the name of the item.<br />
		item1.setName(&quot;Pink Stuffed Bunny&quot;);<br />
		// Sets the ID. This is any ID that you would like to have associated<br />
		// with the item.<br />
		item1.setID(&quot;87239&quot;);<br />
		// Sets the total price which should be (quantity * unit price). The<br />
		// total prices of all PayPalInvoiceItem should add up<br />
		// to less than or equal the subtotal of the payment.<br />
		item1.setTotalPrice(new BigDecimal(&quot;6.00&quot;));<br />
		// Sets the unit price.<br />
		item1.setUnitPrice(new BigDecimal(&quot;2.00&quot;));<br />
		// Sets the quantity.<br />
		item1.setQuantity(3);<br />
		// Add the PayPalInvoiceItem to the PayPalInvoiceData. Alternatively,<br />
		// you can create an ArrayList&lt;PayPalInvoiceItem&gt;<br />
		// and pass it to the PayPalInvoiceData function setInvoiceItems().<br />
		invoice.getInvoiceItems().add(item1);</p>
<p>		// Sets the PayPalPayment invoice data.<br />
		payment.setInvoiceData(invoice);<br />
		// Sets the merchant name. This is the name of your Application or<br />
		// Company.<br />
		payment.setMerchantName(&quot;The Gift Store&quot;);<br />
		// Sets the description of the payment.<br />
		payment.setDescription(&quot;Quite a simple payment&quot;);<br />
		// Sets the Custom ID. This is any ID that you would like to have<br />
		// associated with the payment.<br />
		payment.setCustomID(&quot;8873482296&quot;);<br />
		// Sets the Instant Payment Notification url. This url will be hit by<br />
		// the PayPal server upon completion of the payment.<br />
		payment.setIpnUrl(&quot;http://www.exampleapp.com/ipn&quot;);<br />
		// Sets the memo. This memo will be part of the notification sent by<br />
		// PayPal to the necessary parties.<br />
		payment.setMemo(&quot;Hi! I'm making a memo for a simple payment.&quot;);</p>
<p>		return payment;<br />
	}</p>
<p>	/**<br />
	 * AsyncTask to init a simple Paypal buttom<br />
	 *<br />
	 * @author http://francho.org<br />
	 *<br />
	 */<br />
	public class InitPayPalLibraryAsyncTask extends<br />
			AsyncTask&lt;Void, Void, Boolean&gt; {<br />
		// The PayPal server to be used - can also be ENV_NONE and ENV_LIVE<br />
		private static final int PAYPAL_SERVER = PayPal.ENV_SANDBOX;<br />
		// The ID of your application that you received from PayPal<br />
		private static final String PAYPAL_APP_ID = &quot;APP-80W284485P519543T&quot;;</p>
<p>		private Context context;<br />
		private OnClickListener onClickListener;</p>
<p>		public InitPayPalLibraryAsyncTask(Context context,<br />
				OnClickListener onClickListener) {<br />
			this.context = context;<br />
			this.onClickListener = onClickListener;<br />
		}</p>
<p>		/**<br />
		 * The hard task (requires connect with the server) will be do in<br />
		 * background<br />
		 */<br />
		@Override<br />
		protected Boolean doInBackground(Void... params) {<br />
			PayPal pp = PayPal.getInstance();<br />
			// If the library is already initialized, then we don't need to<br />
			// initialize it again.<br />
			if (pp == null) {<br />
				// This is the main initialization call that takes in your<br />
				// Context, the Application ID, and the server you would like to<br />
				// connect to.<br />
				pp = PayPal<br />
						.initWithAppID(context, PAYPAL_APP_ID, PAYPAL_SERVER);</p>
<p>				// -- These are required settings.<br />
				pp.setLanguage(&quot;es_ES&quot;); // Sets the language for the library.<br />
				// --</p>
<p>				// -- These are a few of the optional settings.<br />
				// Sets the fees payer. If there are fees for the transaction,<br />
				// this person will pay for them. Possible values are<br />
				// FEEPAYER_SENDER,<br />
				// FEEPAYER_PRIMARYRECEIVER, FEEPAYER_EACHRECEIVER, and<br />
				// FEEPAYER_SECONDARYONLY.<br />
				pp.setFeesPayer(PayPal.FEEPAYER_EACHRECEIVER);<br />
				// Set to true if the transaction will require shipping.<br />
				pp.setShippingEnabled(false);<br />
				// Dynamic Amount Calculation allows you to set tax and shipping<br />
				// amounts based on the user's shipping address. Shipping must<br />
				// be<br />
				// enabled for Dynamic Amount Calculation. This also requires<br />
				// you to create a class that implements PaymentAdjuster and<br />
				// Serializable.<br />
				pp.setDynamicAmountCalculationEnabled(false);<br />
				// --<br />
			}</p>
<p>			return PayPal.getInstance().isLibraryInitialized();<br />
		}</p>
<p>		/**<br />
		 * When the library init is finished, setup the pay button<br />
		 */<br />
		@Override<br />
		protected void onPostExecute(Boolean isLibraryInitOk) {<br />
			if (isLibraryInitOk) {<br />
				PayPal pp = PayPal.getInstance();</p>
<p>				CheckoutButton launchSimplePayment = pp.getCheckoutButton(<br />
						context, PayPal.BUTTON_194x37, CheckoutButton.TEXT_PAY);<br />
				// You'll need to have an OnClickListener for the<br />
				// CheckoutButton. For this application, MPL_Example implements<br />
				// OnClickListener and we<br />
				// have the onClick() method below.<br />
				launchSimplePayment.setOnClickListener(onClickListener);<br />
				// The CheckoutButton is an android LinearLayout so we can add<br />
				// it to our display like any other View.</p>
<p>				ViewGroup paypalLayout = (ViewGroup) findViewById(R.id.PayPalBtnContainer);</p>
<p>				paypalLayout.addView(launchSimplePayment);<br />
			} else {<br />
				Toast.makeText(context,<br />
						&quot;Error al inicializar la libreria de paypal&quot;,<br />
						Toast.LENGTH_LONG);<br />
			}<br />
		}</p>
<p>	}</p>
<p>}</p>
<p>