添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
open search

Hi,

i'm new to visa, and trying to integrate Visa SDK for android, the sample can successfully run at my android studio. But when I copy the function to my current Payment Class, this error appear when i click visa payment button.

Here is the complete message :

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.package.name/com.visa.checkout.VisaMcomActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2338)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5299)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:825)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.visa.checkout.utils.aux.<init>(:17)
at com.visa.checkout.g.ˎ.ˎ(:48)
at com.visa.checkout.VisaActivity.onCreate(:122)
at com.visa.checkout.VisaMcomActivity.onCreate(:14)
at android.app.Activity.performCreate(Activity.java:5264)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2302)

We have been working on the error that you have highlighted . To take this further , need a few more details

  • What version of Visa Checkout SDK are you using?
  • What is the version of the device OS?
  • Is the device a rooted phone?
  • Snippet of vInit configuration? (Hint: probably didn’t add the merchant api key)
  • app Activity or Fragment code snippet where you are trying to initialize the SDK?
  • Hi,

    1. Visa 3.5

    2. Device OS is vary from jellybean to marshamallow

    3. Also vary, have rooted and non-rooted too. Tested on both.

    4.

    I still use code from sample :

    I copy the whole sample into my app, and the sample code can run.

    But when integrating into my activity, got that error.

    Below is the code :

    Spoiler
    private void initializeVisaCheckoutSdk() {
    VisaEnvironmentConfig visaEnvironmentConfig = VISA_CHECKOUT_ENVIRONMENT_CONFIG;

    /** Optional: a non-empty profile name obtained during enrollment can be included here. */
    visaEnvironmentConfig.setMerchantProfileName(VISA_CHECKOUT_PROFILE_NAME);

    /** Required. Merchant API key obtained after enrollment. */
    visaEnvironmentConfig.setMerchantApiKey(VISA_CHECKOUT_API_KEY);

    /** Required for EXOButton integration only. Optional for VisaPaymentButton and CustomView integration.
    * RequestCode to start SDK activity with, may be used in onActivityResult() as indicator that result came from the SDK. */
    visaEnvironmentConfig.setVisaCheckoutRequestCode(VISA_CHECKOUT_REQUEST_CODE);

    /** getLibrary should be invoked when the activity/application is created. getLibrary initializes the SDK
    in the background and makes the launch faster when user clicks the checkout button/view. */
    visaMcomLibrary = VisaMcomLibrary.getLibrary(this, visaEnvironmentConfig);
    }

    public class ConfigureVisaPaymentInfo {

    /** Unique return code to identify Visa Checkout Activity's return status */
    public final static int VISA_CHECKOUT_REQUEST_CODE = 10102;

    /** Key for passing Result between activities */
    public final static String VISA_CHECKOUT_RESULT_MSG_KEY = "VisaCheckoutResult";

    /** Key for passing VisaPaymentInfo between activities */
    public final static String VISA_CHECKOUT_REFERENCE_ID_KEY = "VisaCheckoutReferenceId";

    /** REQUIRED. Endpoint configuration for Visa Checkout SDK. Can be PRODUCTION or SANDBOX. */
    public static VisaEnvironmentConfig VISA_CHECKOUT_ENVIRONMENT_CONFIG = VisaEnvironmentConfig.SANDBOX;

    /** Merchant API key obtained during enrollment */
    public final static String VISA_CHECKOUT_API_KEY = "LXFQZOKJIXXFYO20OMI313Hal2ScbAZYETLKqaXZpHFqZ8bDw";

    /** OPTIONAL. Merchant Profile name if any */
    public static String VISA_CHECKOUT_PROFILE_NAME = "defaultprofile";

    public static VisaPaymentInfo getSampleVisaPaymentInfo() {
    VisaPaymentInfo paymentInfo = new VisaPaymentInfo();
    /** REQUIRED: If merchant needs to collect shipping address from the user */
    paymentInfo.setUsingShippingAddress(true);
    /** (REQUIRED if total amount is set): Standard ISO format currency code.
    * Example USD, CAD, AUD
    */
    paymentInfo.setCurrency("USD");
    /** (REQUIRED if currency is set): The total amount for current session in
    * BigDecimal format with a max 2 decimal places and greater than or equal to 0 */
    paymentInfo.setTotal(new BigDecimal("12.34"));
    /** OPTIONAL (CONTINUE by default): Action merchant wants to take whether to Pay
    * or Continue. If amount is not set, it should be Continue.
    * Enum values: UserReviewAction.CONTINUE or UserReviewAction.PAY
    */
    paymentInfo.setUserReviewAction(VisaPaymentInfo.UserReviewAction.CONTINUE);
    /** REQUIRED: The subtotal amount for current session in BigDecimal format with a
    * max 2 decimal places and greater than or equal to zero
    */
    paymentInfo.setSubtotal(new BigDecimal("12.34"));
    /** OPTIONAL: The tax amount for current session in BigDecimal format with a
    * max 2 decimal places and greater than or equal to zero
    */
    paymentInfo.setTax(new BigDecimal("12.34"));
    /** OPTIONAL: The misc amount for current session in BigDecimal format with a
    * max 2 decimal places and greater than or equal to zero
    */
    paymentInfo.setMisc(new BigDecimal("12.34"));
    /** OPTIONAL: The discount amount for current session in BigDecimal format with a
    * max 2 decimal places and greater than or equal to zero */
    paymentInfo.setDiscount(new BigDecimal("12.34"));
    /** OPTIONAL: The giftwrap amount for current session in BigDecimal format with a
    * max 2 decimal places and greater than or equal to zero
    */
    paymentInfo.setGiftWrap(new BigDecimal("12.34"));
    /** OPTIONAL: Shipping & handling amount for current session in BigDecimal format
    * with a max 2 decimal places and greater than or equal to zero
    */
    paymentInfo.setShippingHandling(new BigDecimal("12.34"));
    /** OPTIONAL: Description for current order (String value) */
    paymentInfo.setDescription("Sample Order Description");
    /** OPTIONAL: Order ID for current transaction (String value) */
    paymentInfo.setOrderId("Order1234567890");
    paymentInfo.setVisaMerchantInfo(getSampleMerchantInfo());

    /** OPTIONAL: 3DS Settings */
    // ThreeDSSetup threeDSSetup = new ThreeDSSetup();
    // threeDSSetup.setThreeDSActive(true);

    // /** OPTIONAL: When True, then 3DS authentication in stream during the Checkout transaction is suppressed;
    // * When False, then the regular 3DS flow will apply, and 3DS authentication will be required in stream, and payer authentication will be required
    // */
    // threeDSSetup.setSuppressThreeDSChallenge(false);
    // paymentInfo.setThreeDSSetup(threeDSSetup);

    return paymentInfo;
    }

    private static VisaMerchantInfo getSampleMerchantInfo() {
    /** Sample for a VisaMerchantInfo object */
    VisaMerchantInfo visaMerchantInfo = new VisaMerchantInfo();
    /** REQUIRED: Merchant API key obtained during onboarding (String) */
    visaMerchantInfo.setMerchantApiKey(VISA_CHECKOUT_API_KEY);
    /** OPTIONAL (SUMMARY by default): Access level for current merchant for the
    * encrypted payment info
    * (ENUM: MerchantDataLevel.SUMMARY or MerchantDataLevel.FULL)
    */
    visaMerchantInfo.setDataLevel(VisaMerchantInfo.MerchantDataLevel.SUMMARY);
    /** OPTIONAL: Logo Resource to display during the review screen (int) */
    visaMerchantInfo.setLogoResourceId(R.drawable.ic_vxo_sample_app);
    /** OPTIONAL: Name to display on the review screen for the merchant (String) */
    visaMerchantInfo.setDisplayName("Sample Merchant Name");
    /** OPTIONAL: External profile Id of the Merchant. Only specify if there is one. (String) */
    visaMerchantInfo.setExternalProfileId(VISA_CHECKOUT_PROFILE_NAME);
    /** OPTIONAL: Merchant ID obtained during onboarding (String) */
    visaMerchantInfo.setMerchantId("212");
    /** OPTIONAL (false by default): Whether the current merchant wants to accept
    * Canadian Visa Debit cards (boolean)
    */
    visaMerchantInfo.setAcceptCanadianVisaDebit(false);
    /** OPTIONAL - List of shipping address regions merchant wants to accept for current
    * transaction. (List of AcceptedShippingRegions Enum)
    */
    visaMerchantInfo.setAcceptedShippingRegions(getAcceptedShippingRegions());
    /** OPTIONAL - List of card brands that merchant wants to accept for current
    * transaction. (List of AcceptedCardBrands Enum)
    */
    visaMerchantInfo.setAcceptedCardBrands(getAcceptedCardBrands());
    /** OPTIONAL - List of billing address regions merchant wants to accept for current
    * transaction. (List of AcceptedShippingRegions Enum)
    */
    visaMerchantInfo.setAcceptedBillingRegions(getAcceptedBillingRegions());
    return visaMerchantInfo;
    }

    private static List<VisaMerchantInfo.AcceptedCardBrands> getAcceptedCardBrands(){
    /** Current AcceptedCardBrands values - AcceptedCardBrands.VISA,
    * AcceptedCardBrands.AMEX, AcceptedCardBrands.DISCOVER,
    * AcceptedCardBrands.MASTERCARD
    */
    List<VisaMerchantInfo.AcceptedCardBrands> acb =
    new ArrayList<VisaMerchantInfo.AcceptedCardBrands>();
    acb.add(VisaMerchantInfo.AcceptedCardBrands.VISA);
    acb.add(VisaMerchantInfo.AcceptedCardBrands.AMEX);
    acb.add(VisaMerchantInfo.AcceptedCardBrands.DISCOVER);
    acb.add(VisaMerchantInfo.AcceptedCardBrands.MASTERCARD);
    return acb;
    }

    private static List<VisaMerchantInfo.AcceptedShippingRegions> getAcceptedShippingRegions() {
    /** Current AcceptedShippingRegions */

    List<VisaMerchantInfo.AcceptedShippingRegions> acceptedShippingRegions = new ArrayList<VisaMerchantInfo.AcceptedShippingRegions>();
    acceptedShippingRegions.add(VisaMerchantInfo.AcceptedShippingRegions.US);
    acceptedShippingRegions.add(VisaMerchantInfo.AcceptedShippingRegions.CA);
    acceptedShippingRegions.add(VisaMerchantInfo.AcceptedShippingRegions.AU);
    acceptedShippingRegions.add(VisaMerchantInfo.AcceptedShippingRegions.CN);
    acceptedShippingRegions.add(VisaMerchantInfo.AcceptedShippingRegions.AR);
    acceptedShippingRegions.add(VisaMerchantInfo.AcceptedShippingRegions.CL);
    acceptedShippingRegions.add(VisaMerchantInfo.AcceptedShippingRegions.MX);
    acceptedShippingRegions.add(VisaMerchantInfo.AcceptedShippingRegions.PE);
    acceptedShippingRegions.add(VisaMerchantInfo.AcceptedShippingRegions.ZA);
    acceptedShippingRegions.add(VisaMerchantInfo.AcceptedShippingRegions.NZ);
    acceptedShippingRegions.add(VisaMerchantInfo.AcceptedShippingRegions.AE);
    acceptedShippingRegions.add(VisaMerchantInfo.AcceptedShippingRegions.CO);
    acceptedShippingRegions.add(VisaMerchantInfo.AcceptedShippingRegions.BR);
    acceptedShippingRegions.add(VisaMerchantInfo.AcceptedShippingRegions.SG);
    acceptedShippingRegions.add(VisaMerchantInfo.AcceptedShippingRegions.MY);
    return acceptedShippingRegions;
    }

    private static List<VisaMerchantInfo.AcceptedBillingRegions> getAcceptedBillingRegions() {

    /** Current AcceptedBillingRegions */

    List<VisaMerchantInfo.AcceptedBillingRegions> acceptedBillingRegions = new ArrayList<VisaMerchantInfo.AcceptedBillingRegions>();
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.US);
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.CA);
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.AU);
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.CN);
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.AR);
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.CL);
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.MX);
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.PE);
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.ZA);
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.NZ);
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.AE);
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.CO);
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.BR);
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.HK);
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.SG);
    acceptedBillingRegions.add(VisaMerchantInfo.AcceptedBillingRegions.MY);

    return acceptedBillingRegions;
    }

    Thank you for the inputs. We are working on this question and looking for a couple of more details

  • Need code snippet used for SDK initialization
  • Version of Android VCO SDK version
  • Gradle version and build tool version used
  • Manifest file configuration
  • Hi,

    1. Need code snippet used for SDK initialization

        private void initializeVisaCheckoutSdk() {
            VisaEnvironmentConfig visaEnvironmentConfig = VISA_CHECKOUT_ENVIRONMENT_CONFIG;
            /** Optional: a non-empty profile name obtained during enrollment can be included here. */
            visaEnvironmentConfig.setMerchantProfileName(VISA_CHECKOUT_PROFILE_NAME);
            /** Required. Merchant API key obtained after enrollment. */
            visaEnvironmentConfig.setMerchantApiKey(VISA_CHECKOUT_API_KEY);
            /** Required for EXOButton integration only. Optional for VisaPaymentButton and CustomView integration.
             *  RequestCode to start SDK activity with, may be used in onActivityResult() as indicator that result came from the SDK. */
            visaEnvironmentConfig.setVisaCheckoutRequestCode(VISA_CHECKOUT_REQUEST_CODE);
            /** getLibrary should be invoked when the activity/application is created. getLibrary initializes the SDK
             in the background and makes the launch faster when user clicks the checkout button/view.  */
            visaMcomLibrary = VisaMcomLibrary.getLibrary(this, visaEnvironmentConfig);
        }

    2. Version of Android VCO SDK version -> version 3.7 (the latest)

    3.Gradle version and build tool version used -> gradle 2.0.0 &

    buildToolsVersion = "21.1.2"

    4.Manifest file configuration

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/apk/res-auto"
              package="com.gscandroid.yk"
        android:versionCode="32"
        android:versionName="2.3.4"
        <permission
            android:name="com.gscandroid.yk.permission.MAPS_RECEIVE"
            android:protectionLevel="signature" />
        <uses-feature
            android:glEsVersion="0x00020000"
            android:required="true" />
        <uses-permission android:name="com.example.gsc.permission.MAPS_RECEIVE" />
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.READ_PHONE_STATE" />
        <uses-permission android:name="android.permission.READ_LOGS" />
        <uses-permission android:name="android.permission.GET_TASKS" />
        <uses-permission android:name="android.permission.READ_CALENDAR" />
        <uses-permission android:name="android.permission.WRITE_CALENDAR" />
        <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-feature
            android:name="android.hardware.location"
            android:required="true" />
        <uses-feature
            android:name="android.hardware.location.gps"
            android:required="false" />
        <!-- card.io: Permission to use camera - required -->
        <uses-permission android:name="android.permission.CAMERA" />
        <!-- card.io: Permission to vibrate - recommended, allows vibration feedback on scan -->
        <uses-permission android:name="android.permission.VIBRATE" />
        <!--  Android Fingerprint -->
        <uses-permission android:name="android.permission.USE_FINGERPRINT" />
        <!-- Samsung pass -->
        <uses-permission android:name= "com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY"/>
        <!-- card.io: Camera features - recommended -->
        <uses-feature android:name="android.hardware.camera" android:required="false" />
        <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
        <uses-feature android:name="android.hardware.camera.flash" android:required="false" />
        <!-- android:debuggable="false" -->
        <application
            android:allowBackup="false"
            android:allowClearUserData="false"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/NormalTheme" >
            <uses-library android:name="com.google.android.maps" />
            <meta-data
                android:name="com.google.android.maps.v2.API_KEY"
                android:value="@string/google_api_key" />
            <meta-data
                android:name="com.facebook.sdk.ApplicationId"
                android:value="@string/facebook_app_id" />
            <activity android:name="com.facebook.LoginActivity" >
            </activity>
            <activity
                android:name=".activities.PaymentActivity"
                android:label="@string/app_name"
                android:screenOrientation="portrait" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>
            </activity>
            <activity android:name="com.visa.PaymentStartActivity">
                <!--<intent-filter>-->
                    <!--<action android:name="android.intent.action.MAIN" />-->
                    <!--<category android:name="android.intent.category.LAUNCHER" />-->
                <!--</intent-filter>-->
            </activity>
            <activity android:name="com.visa.checkout.VisaMcomActivity" android:configChanges="layoutDirection"/>
            <!-- Activities responsible for gathering payment info via card.io -->
            <activity android:name="io.card.payment.CardIOActivity"
                      android:configChanges="keyboardHidden|orientation"
                      android:screenOrientation="portrait"
                      android:hardwareAccelerated="true" />
            <activity android:name="io.card.payment.DataEntryActivity"
                      android:screenOrientation="portrait" />
        </application>
    </manifest>

    After going through the details and comparing the scenario across different use cases, the potential reasons for the behavior could be that the values that are mandatory for SDK initialisation not present (need to pass all mandatory files in VisaPayment and MerchantInfo Object)

    We would recommend the following and revert

  • Check if sample app works with all the configuration ( API key, supported cards, billing address and shipping address configuration etc., )
  • Compare the Developer app with sample app to make sure SDK in initialized correctly
  •