Skip to content
This repository has been archived by the owner on Jun 11, 2021. It is now read-only.

PayPal for Android won't switch to Production environment #420

Closed
mahdihijazi opened this issue Jul 28, 2017 · 20 comments
Closed

PayPal for Android won't switch to Production environment #420

mahdihijazi opened this issue Jul 28, 2017 · 20 comments
Labels

Comments

@mahdihijazi
Copy link

So I'have integrated paypal-android-sdk:2.15.3 in my app and it works as expected in Sandbox. Now I want to move to production.

I switched the environment to PayPalConfiguration.ENVIRONMENT_PRODUCTION And the client id to the production client id. What happens is that first I can't login using my real PayPal account, second I see the blue Sandbox button as below screenshot:

Screenshot

My Code:

PayPalConfiguration config = new PayPalConfiguration()
                .environment(CustomBuildConfig.PAY_PAL_CONFIG_ENVIRONMENT)
                .clientId(CustomBuildConfig.PAY_PAL_CONFIG_CLIENT_ID);

        PayPalPayment thingToBuy = new PayPalPayment(new BigDecimal(value), currency, item,
                PayPalPayment.PAYMENT_INTENT_SALE);
        Intent intent = new Intent(getContext(), PaymentActivity.class);
        intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
        intent.putExtra(PaymentActivity.EXTRA_PAYMENT, thingToBuy);
        startActivityForResult(intent, REQUEST_CODE_PAYPAL_PAYMENT);

Where:

PAY_PAL_CONFIG_ENVIRONMENT = PayPalConfiguration.ENVIRONMENT_PRODUCTION; PAY_PAL_CONFIG_CLIENT_ID = "production client id";

@GemiDroid
Copy link

I am facing the same problem and I have no idea about that .. If you have a solution just email me :
eng.ahmedgemi@gmail.com

@randstraw
Copy link

Can you confirm you are getting the values in the config set correctly? The reason is you would get a invalid merchant error if you are using your production client id and it is hitting the sandbox.

@GemiDroid
Copy link

No, Client ID is different

@randstraw
Copy link

@GemiDroid minus your client id, what does your configuration look like?

@GemiDroid
Copy link

Can I get ur email or any communication tool?

@randstraw
Copy link

You can file a ticket with PayPal Technical Support here: https://www.paypal-techsupport.com/app/ask

@GemiDroid
Copy link

I have already done

@randstraw
Copy link

@mahdihijazi can you confirm these values are being set correctly? I ran a test on live and it worked fine.

@GemiDroid
Copy link

I need any help @pp-randy ?

@randstraw
Copy link

@GemiDroid can you please copy and paste your code for your PayPal configuration so I can see what you are doing? Please remove your client id before providing that.

@GemiDroid
Copy link

package com.orchtech.edaradotcom.activities;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.orchtech.edaradotcom.R;
import com.paypal.android.MEP.PayPal;
import com.paypal.android.sdk.payments.PayPalAuthorization;
import com.paypal.android.sdk.payments.PayPalConfiguration;
import com.paypal.android.sdk.payments.PayPalFuturePaymentActivity;
import com.paypal.android.sdk.payments.PayPalItem;
import com.paypal.android.sdk.payments.PayPalOAuthScopes;
import com.paypal.android.sdk.payments.PayPalPayment;
import com.paypal.android.sdk.payments.PayPalPaymentDetails;
import com.paypal.android.sdk.payments.PayPalProfileSharingActivity;
import com.paypal.android.sdk.payments.PayPalService;
import com.paypal.android.sdk.payments.PaymentActivity;
import com.paypal.android.sdk.payments.PaymentConfirmation;
import com.paypal.android.sdk.payments.ShippingAddress;

import org.json.JSONException;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**

  • THIS FILE IS OVERWRITTEN BY `androidSDK/src/<general|partner>sampleAppJava.

  • ANY UPDATES TO THIS FILE WILL BE REMOVED IN RELEASES.

  • Basic sample using the SDK to make a payment or consent to future payments.

  • For sample mobile backend interactions, see

  • https://github.com/paypal/rest-api-sdk-python/tree/master/samples/mobile_backend
    /
    public class PaypalActivity extends AppCompatActivity {
    private static final String TAG = "paymentExample";
    /
    *

      • Set to PayPalConfiguration.ENVIRONMENT_PRODUCTION to move real money.
      • Set to PayPalConfiguration.ENVIRONMENT_SANDBOX to use your test credentials
    • from https://developer.paypal.com
      • Set to PayPalConfiguration.ENVIRONMENT_NO_NETWORK to kick the tires
    • without communicating to PayPal's servers.
      */
      private static final String CONFIG_ENVIRONMENT = PayPalConfiguration.ENVIRONMENT_PRODUCTION;
      // note that these credentials will differ between live & sandbox environments.

    private static final int REQUEST_CODE_PAYMENT = 1;
    private static final int REQUEST_CODE_FUTURE_PAYMENT = 2;
    private static final int REQUEST_CODE_PROFILE_SHARING = 3;

    private static PayPalConfiguration config = new PayPalConfiguration()
    .environment(CONFIG_ENVIRONMENT)
    .clientId(CONFIG_CLIENT_ID_LIVE)
    // The following are only used in PayPalFuturePaymentActivity.
    .merchantName("edara.com")
    .merchantPrivacyPolicyUri(Uri.parse("https://edara.com/PrivacyPolicy/"))
    .merchantUserAgreementUri(Uri.parse("https://edara.com/PrivacyPolicy/"));

    @OverRide
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_paypal);

     Intent intent = new Intent(this, PayPalService.class);
     intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
     startService(intent);
     /*onBuyPressed(findViewById(R.id.buyItBtn));*/
    
     onBuyPressed();
    

    }
    /*

    @OverRide
    public void onBackPressed() {
    this.finish();
    //super.onBackPressed();
    }
    */

    @OverRide
    protected void onStop() {
    finish();
    super.onStop();
    }

    public void onBuyPressed() {
    /*
    * PAYMENT_INTENT_SALE will cause the payment to complete immediately.
    * Change PAYMENT_INTENT_SALE to
    * - PAYMENT_INTENT_AUTHORIZE to only authorize payment and capture funds later.
    * - PAYMENT_INTENT_ORDER to create a payment for authorization and capture
    * later via calls from your server.
    *
    * Also, to include additional payment details and an item list, see getStuffToBuy() below.
    */
    PayPalPayment thingToBuy = getThingToBuy(PayPalPayment.PAYMENT_INTENT_SALE);

     /*
      * See getStuffToBuy(..) for examples of some available payment options.
      */
    
     Intent intent = new Intent(this, PaymentActivity.class);
    
     // send the same configuration for restart resiliency
     intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
    
     intent.putExtra(PaymentActivity.EXTRA_PAYMENT, thingToBuy);
    
     startActivityForResult(intent, REQUEST_CODE_PAYMENT);
    

    }

    private PayPalPayment getThingToBuy(String paymentIntent) {

     Bundle i = getIntent().getExtras();
     String Amount = i.getString("amount");
     //String ShoppingCart = i.getString("shopping_cart");
    
    
     return new PayPalPayment(new BigDecimal(Amount), "USD", "Invoice Cost :",
             paymentIntent);
    

    }

    /*

    • This method shows use of optional payment details and item list.
      */
      private PayPalPayment getStuffToBuy(String paymentIntent) {
      //--- include an item list, payment amount details
      PayPalItem[] items =
      {
      new PayPalItem("sample item Integrating PayPal Android SDK into kiosk #1", 2, new BigDecimal("87.50"), "USD",
      "sku-12345678"),
      new PayPalItem("free sample item Support for non-US transactions #2", 1, new BigDecimal("0.00"),
      "USD", "sku-zero-price"),
      new PayPalItem("sample item The app crashes, I tried with different emulators but it always crashes. #3 with a longer name", 6, new BigDecimal("37.99"),
      "USD", "sku-33333")
      };
      BigDecimal subtotal = PayPalItem.getItemTotal(items);
      BigDecimal shipping = new BigDecimal("7.21");
      BigDecimal tax = new BigDecimal("4.67");
      PayPalPaymentDetails paymentDetails = new PayPalPaymentDetails(shipping, subtotal, tax);
      BigDecimal amount = subtotal.add(shipping).add(tax);
      PayPalPayment payment = new PayPalPayment(amount, "USD", "sample item", paymentIntent);
      payment.items(items).paymentDetails(paymentDetails);

      //--- set other optional fields like invoice_number, custom field, and soft_descriptor
      payment.custom("This is text that will be associated with the payment that the app can use.");

      return payment;
      }

    /*

    • Add app-provided shipping address to payment
      */
      private void addAppProvidedShippingAddress(PayPalPayment paypalPayment) {
      ShippingAddress shippingAddress =
      new ShippingAddress().recipientName("Mom Parker").line1("52 North Main St.")
      .city("Austin").state("TX").postalCode("78729").countryCode("US");
      paypalPayment.providedShippingAddress(shippingAddress);
      }

    /*

    • Enable retrieval of shipping addresses from buyer's PayPal account
      */
      private void enableShippingAddressRetrieval(PayPalPayment paypalPayment, boolean enable) {
      paypalPayment.enablePayPalShippingAddressesRetrieval(enable);
      }

    public void onFuturePaymentPressed(View pressed) {
    Intent intent = new Intent(this, PayPalFuturePaymentActivity.class);

     // send the same configuration for restart resiliency
     intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
    
     startActivityForResult(intent, REQUEST_CODE_FUTURE_PAYMENT);
    

    }

    public void onProfileSharingPressed(View pressed) {
    Intent intent = new Intent(this, PayPalProfileSharingActivity.class);

     // send the same configuration for restart resiliency
     intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
    
     intent.putExtra(PayPalProfileSharingActivity.EXTRA_REQUESTED_SCOPES, getOauthScopes());
    
     startActivityForResult(intent, REQUEST_CODE_PROFILE_SHARING);
    

    }

    private PayPalOAuthScopes getOauthScopes() {
    /* create the set of required scopes
    * Note: see https://developer.paypal.com/docs/integration/direct/identity/attributes/ for mapping between the
    * attributes you select for this app in the PayPal developer portal and the scopes required here.
    */
    Set scopes = new HashSet(
    Arrays.asList(PayPalOAuthScopes.PAYPAL_SCOPE_EMAIL, PayPalOAuthScopes.PAYPAL_SCOPE_ADDRESS));
    return new PayPalOAuthScopes(scopes);
    }

    protected void displayResultText(String result) {
    ((TextView) findViewById(R.id.txtResult)).setText("Result : " + result);
    Toast.makeText(
    getApplicationContext(),
    result, Toast.LENGTH_LONG)
    .show();
    }

    @OverRide
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

     if (requestCode == REQUEST_CODE_PAYMENT) {
         if (resultCode == Activity.RESULT_OK) {
             PaymentConfirmation confirm =
                     data.getParcelableExtra(PaymentActivity.EXTRA_RESULT_CONFIRMATION);
             if (confirm != null) {
                 try {
                     Log.i(TAG, confirm.toJSONObject().toString(4));
                     Log.i(TAG, confirm.getPayment().toJSONObject().toString(4));
    
                     /**
                      *  TODO: send 'confirm' (and possibly confirm.getPayment() to your server for verification
                      * or consent completion.
                      * See https://developer.paypal.com/webapps/developer/docs/integration/mobile/verify-mobile-payment/
                      * for more details.
                      *
                      * For sample mobile backend interactions, see
                      * https://github.com/paypal/rest-api-sdk-python/tree/master/samples/mobile_backend
                      */
                     displayResultText("PaymentConfirmation info received from PayPal");
                     Toast.makeText(this, "Successed", Toast.LENGTH_SHORT).show();
                     /*Intent i = new Intent(this, ActivityHomePage.class);
                     i.putExtra("payment_status", confirm.getProofOfPayment().getState());*/
                     //  this.finish();
    
                     // Toast.makeText(this,confirm.getProofOfPayment().getState(),Toast.LENGTH_SHORT).show();
    
                 } catch (JSONException e) {
                     Log.e(TAG, "an extremely unlikely failure occurred: ", e);
                 }
             }
         } else if (resultCode == Activity.RESULT_CANCELED) {
             Log.i(TAG, "The user canceled.");
         } else if (resultCode == PaymentActivity.RESULT_EXTRAS_INVALID) {
             Log.i(
                     TAG,
                     "An invalid Payment or PayPalConfiguration was submitted. Please see the docs.");
         }
     } else if (requestCode == REQUEST_CODE_FUTURE_PAYMENT) {
         if (resultCode == Activity.RESULT_OK) {
             PayPalAuthorization auth =
                     data.getParcelableExtra(PayPalFuturePaymentActivity.EXTRA_RESULT_AUTHORIZATION);
             if (auth != null) {
                 try {
                     Log.i("FuturePaymentExample", auth.toJSONObject().toString(4));
    
                     String authorization_code = auth.getAuthorizationCode();
                     Log.i("FuturePaymentExample", authorization_code);
    
                     sendAuthorizationToServer(auth);
                     displayResultText("Future Payment code received from PayPal");
    
                 } catch (JSONException e) {
                     Log.e("FuturePaymentExample", "an extremely unlikely failure occurred: ", e);
                 }
             }
         } else if (resultCode == Activity.RESULT_CANCELED) {
             Log.i("FuturePaymentExample", "The user canceled.");
         } else if (resultCode == PayPalFuturePaymentActivity.RESULT_EXTRAS_INVALID) {
             Log.i(
                     "FuturePaymentExample",
                     "Probably the attempt to previously start the PayPalService had an invalid PayPalConfiguration. Please see the docs.");
         }
     } else if (requestCode == REQUEST_CODE_PROFILE_SHARING) {
         if (resultCode == Activity.RESULT_OK) {
             PayPalAuthorization auth =
                     data.getParcelableExtra(PayPalProfileSharingActivity.EXTRA_RESULT_AUTHORIZATION);
             if (auth != null) {
                 try {
                     Log.i("ProfileSharingExample", auth.toJSONObject().toString(4));
    
                     String authorization_code = auth.getAuthorizationCode();
                     Log.i("ProfileSharingExample", authorization_code);
    
                     sendAuthorizationToServer(auth);
                     displayResultText("Profile Sharing code received from PayPal");
    
                 } catch (JSONException e) {
                     Log.e("ProfileSharingExample", "an extremely unlikely failure occurred: ", e);
                 }
             }
         } else if (resultCode == Activity.RESULT_CANCELED) {
             Log.i("ProfileSharingExample", "The user canceled.");
         } else if (resultCode == PayPalFuturePaymentActivity.RESULT_EXTRAS_INVALID) {
             Log.i(
                     "ProfileSharingExample",
                     "Probably the attempt to previously start the PayPalService had an invalid PayPalConfiguration. Please see the docs.");
         }
     }
    

    }

    private void sendAuthorizationToServer(PayPalAuthorization authorization) {

     /**
      * TODO: Send the authorization response to your server, where it can
      * exchange the authorization code for OAuth access and refresh tokens.
      *
      * Your server must then store these tokens, so that your server code
      * can execute payments for this user in the future.
      *
      * A more complete example that includes the required app-server to
      * PayPal-server integration is available from
      * https://github.com/paypal/rest-api-sdk-python/tree/master/samples/mobile_backend
      */
    

    }

    public void onFuturePaymentPurchasePressed(View pressed) {
    // Get the Client Metadata ID from the SDK
    String metadataId = PayPalConfiguration.getClientMetadataId(this);

     Log.i("FuturePaymentExample", "Client Metadata ID: " + metadataId);
    
     // TODO: Send metadataId and transaction details to your server for processing with
     // PayPal...
     displayResultText("Client Metadata Id received from SDK");
    

    }

    @OverRide
    public void onDestroy() {
    // Stop service when done
    stopService(new Intent(this, PayPalService.class));
    super.onDestroy();
    }

    public void initLibrary() {
    PayPal pp = PayPal.getInstance();

     if (pp == null) {  // Test to see if the library is already initialized
    
         // This main initialization call takes your Context, AppID, and target server
         pp = PayPal.initWithAppID(this, "APP-80W284485P519543T", PayPal.ENV_SANDBOX);
    
         // Required settings:
    
         // Set the language for the library
         pp.setLanguage("en_US");
    
         // Some Optional settings:
    
         // Sets who pays any transaction fees. Value is:
         // FEEPAYER_SENDER, FEEPAYER_PRIMARYRECEIVER, FEEPAYER_EACHRECEIVER, and FEEPAYER_SECONDARYONLY
         pp.setFeesPayer(PayPal.FEEPAYER_EACHRECEIVER);
    
         // true = transaction requires shipping
         pp.setShippingEnabled(true);
    
         // _paypalLibraryInit = true;
     }
    

    }
    }

@randstraw
Copy link

You have the legacy library code here, which is showing sandbox.
pp = PayPal.initWithAppID(this, "APP-80W284485P519543T", PayPal.ENV_SANDBOX);

What type of payment are you trying to make?

What error are you seeing?

@GemiDroid
Copy link

initLibrary isn't used in My App

I buy books

screenshot_2017-08-01-13-24-42 1

@randstraw
Copy link

randstraw commented Aug 1, 2017

Your screen shot is for a different issue than what is filed here. Can you please create a new one. Also can you capture LogCat details for this error?

@GemiDroid
Copy link

11

And I am in Production :

1- private static final String CONFIG_ENVIRONMENT = PayPalConfiguration.ENVIRONMENT_PRODUCTION;

2- private static PayPalConfiguration config = new PayPalConfiguration()
.environment(CONFIG_ENVIRONMENT)
.clientId(CONFIG_CLIENT_ID_LIVE);

@GemiDroid
Copy link

Is there any updates, please help @pp-randy

@randstraw
Copy link

I pulled your logs from the debug id in the screen shot. You are trying to pay yourself. You need a separate payer account than that in the REST App. If you are passing in a payee, that is the receiver and not the payer / buyer.

@randstraw
Copy link

@GemiDroid please create a new issue in this repo if you have further issues. I still need to verify that @mahdihijazi is not having an issue at this point.

@GemiDroid
Copy link

Ok, thanks @pp-randy

@braebot
Copy link
Contributor

braebot commented Aug 11, 2017

Closing issue due to lack of response from original creator.

@braebot braebot closed this as completed Aug 11, 2017
@paypal paypal locked and limited conversation to collaborators Aug 14, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants