Runtime Error: Class extends value [object Object] is not a constructor or null

1.8k views Asked by At

I want to replicate a braintree demo app using ionic 3.

I have imported braintree with... import * as braintree from 'braintree';

but I am not able to connect to braintree.

The message reads... "Runtime Error: Class extends value [object Object] is not a constructor or null"

This is the code in my ts file

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, ViewController } from 'ionic-angular';

import * as braintree from 'braintree';

@IonicPage()
@Component({
  selector: 'page-apply',
  templateUrl: 'apply.html',
})

export class ApplyPage {

  gateway: any;

  constructor(public navCtrl: NavController, public navParams: NavParams, public viewCtrl: ViewController) {
    this.gateway = braintree.connect({
      environment:  braintree.Environment.Sandbox,
      merchantId:   'personalMerchantId',
      publicKey:    'personalPublicKey',
      privateKey:   'personalPrivateKey'
    });
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad ApplyPage');
  }


}

This is the code within the index.js file of the module

'use strict';

module.exports = require('./lib/braintree');

And this code sits in the braintree.js file of which index.js points to

'use strict';

let version = require('../package.json').version;
let Config = require('./braintree/config').Config;
let Environment = require('./braintree/environment').Environment;
let BraintreeGateway = require('./braintree/braintree_gateway').BraintreeGateway;
let errorTypes = require('./braintree/error_types').errorTypes;

let Transaction = require('./braintree/transaction').Transaction;

let CreditCard = require('./braintree/credit_card').CreditCard;
let PayPalAccount = require('./braintree/paypal_account').PayPalAccount;
let AndroidPayCard = require('./braintree/android_pay_card').AndroidPayCard;
let ApplePayCard = require('./braintree/apple_pay_card').ApplePayCard;
let VenmoAccount = require('./braintree/venmo_account').VenmoAccount;
let CoinbaseAccount = require('./braintree/coinbase_account').CoinbaseAccount;
let AmexExpressCheckoutCard = require('./braintree/amex_express_checkout_card').AmexExpressCheckoutCard;
let VisaCheckoutCard = require('./braintree/visa_checkout_card').VisaCheckoutCard;
let MasterpassCard = require('./braintree/masterpass_card').MasterpassCard;

let CreditCardVerification = require('./braintree/credit_card_verification').CreditCardVerification;
let Subscription = require('./braintree/subscription').Subscription;
let MerchantAccount = require('./braintree/merchant_account').MerchantAccount;
let PaymentInstrumentTypes = require('./braintree/payment_instrument_types').PaymentInstrumentTypes;
let WebhookNotification = require('./braintree/webhook_notification').WebhookNotification;
let TestingGateway = require('./braintree/testing_gateway').TestingGateway;
let ValidationErrorCodes = require('./braintree/validation_error_codes').ValidationErrorCodes;

let CreditCardDefaults = require('./braintree/test/credit_card_defaults').CreditCardDefaults;
let CreditCardNumbers = require('./braintree/test/credit_card_numbers').CreditCardNumbers;
let MerchantAccountTest = require('./braintree/test/merchant_account').MerchantAccountTest;
let Nonces = require('./braintree/test/nonces').Nonces;
let TransactionAmounts = require('./braintree/test/transaction_amounts').TransactionAmounts;

let connect = config => new BraintreeGateway(new Config(config)); // eslint-disable-line func-style
let Test = {
  CreditCardDefaults: CreditCardDefaults,
  CreditCardNumbers: CreditCardNumbers,
  MerchantAccountTest: MerchantAccountTest,
  Nonces: Nonces,
  TransactionAmounts: TransactionAmounts
};

module.exports = {
  connect: connect,
  version: version,
  Environment: Environment,
  errorTypes: errorTypes,

  Transaction: Transaction,

  CreditCard: CreditCard,
  PayPalAccount: PayPalAccount,
  AndroidPayCard: AndroidPayCard,
  ApplePayCard: ApplePayCard,
  VenmoAccount: VenmoAccount,
  CoinbaseAccount: CoinbaseAccount,
  AmexExpressCheckoutCard: AmexExpressCheckoutCard,
  VisaCheckoutCard: VisaCheckoutCard,
  MasterpassCard: MasterpassCard,

  CreditCardVerification: CreditCardVerification,
  Subscription: Subscription,
  MerchantAccount: MerchantAccount,
  PaymentInstrumentTypes: PaymentInstrumentTypes,
  WebhookNotification: WebhookNotification,
  TestingGateway: TestingGateway,
  ValidationErrorCodes: ValidationErrorCodes,

  Test: Test
};

And this is the code that sits in the index.js file of the working ExpressJs Demo

var express = require('express');
var router = express.Router();
var braintree = require('braintree');

var gateway = braintree.connect({
    environment:  braintree.Environment.Sandbox,
    merchantId:   'personalMerchantID',
    publicKey:    'personalPublicKey',
    privateKey:   'personal_PrivateKey'
});

router.get('/', function(req, res) {
  gateway.clientToken.generate({}, function(err, response) {
    var token = response.clientToken;

    res.render('index', {token : token});
  });
});

router.post('/add', function(req, res) {

  var merchant_id = req.body.merchant_id;
  var bank_account = req.body.bank_account;
  var bank_routing = req.body.bank_routing;

  var merchantAccountParams = {
    individual: {
      firstName: "Jane",
      lastName: "Doe",
      email: "[email protected]",
      phone: "5553334444",
      dateOfBirth: "1981-11-19",
      ssn: "456-45-4567",
      address: {
        streetAddress: "111 Main St",
        locality: "Chicago",
        region: "IL",
        postalCode: "60622"
      }
    },
    funding: {
      destination: braintree.MerchantAccount.FundingDestination.Bank,
      accountNumber: bank_account,
      routingNumber: bank_routing
    },
    tosAccepted: true,
    masterMerchantAccountId: "_my_personal_master_merchant_account_ID",
    id: merchant_id
  };

  gateway.merchantAccount.create(merchantAccountParams, function (err, result) {
    res.render('addResult', {result: result});
  });

});

router.get('/find', function(req, res) {
  var merchant_id = req.query.merchant_id;

  gateway.merchantAccount.find(merchant_id, function(err, result) {
    res.render('findResult', {result: result, merchant_id: merchant_id});
  });

});

router.post('/process', function(req, res) {
  var nonce = req.body.payment_method_nonce;
  var total = req.body.total;
  var service = req.body.service;
  var merchant_id = req.body.merchant_id;

  gateway.transaction.sale({
    amount: total,
    merchantAccountId: merchant_id,
    paymentMethodNonce: nonce,
    serviceFeeAmount: service
  }, function (err, result) {
    res.render('processResult', {result: result});
  });
});

module.exports = router;

Again the above code was produced by braintree. I am sure for demo purposes only.

2

There are 2 answers

4
BladeBarringer On BEST ANSWER

You should not do this.

By including the Braintree node server library in the mobile client, you are exposing your private key to anyone who is using the app. This is highly insecure.

Instead, you should have a server where you can accept a nonce generated by your app to process transactions. The Braintree Cordova Plugin that @Sampath posted looks like a reasonable way to generate a nonce in your app.

7
Sampath On

It seems you're not using any plugin with above implementation. So you have to use one.This is the Braintree Cordova Plugin.

npm install plist
npm install xcode

cordova platform remove ios
cordova plugin add https://github.com/taracque/cordova-plugin-braintree
cordova platform add ios

Here you can see how to add none native plugin to the Ionic app.