Magento 2 - Programatically Add Credit Card into Vault (BrainTree) - magento2

I need to Add Credit Card details in to Vault Programmatically (BrainTree) in Magento 2.1.5
Basically what i want is After LoginIn there will be a separate section for Saved Cards . In that Customer is used to Add/edit/delete All his Credit card details.
the Below Code is used to list all the Credit Card saved by the Customer
use Magento\Vault\Api\PaymentTokenManagementInterface;
use Magento\Customer\Model\Session;
...
// Get the customer id (currently logged in user)
$customerId = $this->session->getCustomer()->getId();
// Card list
$cardList = $this->paymentTokenManagement->getListByCustomerId($customerId);
Now what i want is how to Add the Card Details to the Vault ?
Below is the Code to Add card in core php
$result = Braintree_Customer::create(array(
'firstName' => 'first name',
'lastName' => 'last name',
'company' => 'company',
'email' => 'xxxx#gmail.com',
'phone' => '1234567890',
'creditCard' => array(
'cardholderName' => 'xxx xxx',
'number' => '4000 0000 0000 0002 ',
'expirationMonth' => '10',
'expirationYear' => 2020,
'cvv' => '123',
'billingAddress' => array(
'firstName' => 'My First name',
'lastName' => 'My Last name'
)
)
));
But how can i do this same process in magento 2.
Thanks for the help

First, you have to create a payment token from the card data:
use Magento\Vault\Model\CreditCardTokenFactory;
...
$paymentToken = $this->creditCardTokenFactory->create();
$paymentToken->setExpiresAt('Y-m-d 00:00:00');
$paymentToken->setGatewayToken('card_112371K7-28BB-4O3X-CCG9-1034JHK27D88');
$paymentToken->setTokenDetails([
'type' => 'Visa',
'maskedCC' => '1111',
'expirationDate' => '06/2019'
]);
$paymentToken->setIsActive(true);
$paymentToken->setIsVisible(true);
$paymentToken->setPaymentMethodCode('your_payment_method_code');
$paymentToken->setCustomerId($customerId);
$paymentToken->setPublicHash($this->generatePublicHash($paymentToken));
Then you can save the payment token:
use Magento\Vault\Api\PaymentTokenRepositoryInterface;
...
$this->paymentTokenRepository->save($paymentToken);
This is just an example you can start with. In a real world situation, you would also want to check that the token doesn't already exist, an also try a payment authorisation on the card to make sure it's actually usable and valid.
In order to check if a payment token exists or not, you can use this:
use Magento\Vault\Api\PaymentTokenManagementInterface;
...
$this->paymentTokenManagement->getByPublicHash( $paymentToken->getPublicHash(), $paymentToken->getCustomerId() );
You can have a look at the core Magento 2 classes mentioned here to know more about the functions available for payment token handling.
Good luck!

Replace objectManager when use in projects
<?php
use Magento\Framework\Encryption\EncryptorInterface;
use Magento\TestFramework\Helper\Bootstrap;
use Magento\Vault\Model\AccountPaymentTokenFactory;
use Magento\Vault\Model\PaymentToken;
use Magento\Vault\Model\PaymentTokenRepository;
/** #var EncryptorInterface $encryptor */
$encryptor = $objectManager->get(EncryptorInterface::class);
/** #var PaymentToken $paymentToken */
$paymentToken = $objectManager->create(PaymentToken::class);
$paymentToken
->setCustomerId($customer->getId())
->setPaymentMethodCode('payflowpro')
->setType(AccountPaymentTokenFactory::TOKEN_TYPE_ACCOUNT)
->setGatewayToken('mx29vk')
->setPublicHash($encryptor->hash($customer->getId()))
->setTokenDetails(json_encode(['payerEmail' => 'john.doe#example.com']))
->setIsActive(true)
->setIsVisible(true)
->setExpiresAt(date('Y-m-d H:i:s', strtotime('+1 year')));
/** #var PaymentTokenRepository $tokenRepository */
$tokenRepository = $objectManager->create(PaymentTokenRepository::class);
$tokenRepository->save($paymentToken);

Related

Shippo change shipping rate

I'm using the Shippo API to try and set my rate/parcel to USPS priority. Per the docs I feel like I need to add/edit the $rate array, but I can't seem to figure it out.
// Select the rate you want to purchase.
// We simply select the first rate in this example.
// $rate = $shipment["rates_list"][0];
$rate = array(
'object_state' => 'VALID',
'provider' => 'USPS',
'servicelevel_name' => 'Priority Mail',
'servicelevel_token' => 'usps_priority'
);
// Purchase the desired rate
$transaction = Shippo_Transaction::create(array(
'rate'=> $rate["object_id"],
//'rate' => $rate["usps_priority"],
'async'=> false
));
Looks like our InstaLabel feature is perfect for you https://goshippo.com/shipping-api/instalabel
There is a complete PHP example on that link but here's the bit of code you specified:
$transaction = Shippo_Transaction::create( array(
'shipment' => $shipment,
'carrier_account' => 'b741b99f95e841639b54272834bc478c',
'servicelevel_token' => 'usps_priority',
);
);

How to set up Omnipay with Laravel?

I am using this packet:
https://github.com/barryvdh/laravel-omnipay
In my controller I added:
$params = [
'amount' => '10',
'issuer' => 22,
'description' => 'desc',
'returnUrl' => URL::action('PurchaseController#returnApi', [43]),
];
$response = Omnipay::purchase($params)->send();
if ($response->isSuccessful()) {
// payment was successful: update database
print_r($response);
} elseif ($response->isRedirect()) {
// redirect to offsite payment gateway
return $response->getRedirectResponse();
} else {
// payment failed: display message to customer
echo $response->getMessage();
}
Here is my omnipay.php conf file:
<?php
return array(
/** The default gateway name */
'gateway' => 'PayPal_Express',
/** The default settings, applied to all gateways */
'defaults' => array(
'testMode' => true,
),
/** Gateway specific parameters */
'gateways' => array(
'PayPal_Express' => array(
'username' => '',
'landingPage' => array('billing', 'login'),
),
),
);
But get this error:
call_user_func_array() expects parameter 1 to be a valid callback,
class 'Omnipay\Common\GatewayFactory' does not have a method
'purchase'
Anyone can help me set this?
I created app on paypal and have details about it but don't know how to set it with this API...
I recommend that you switch from PayPal Express to PayPal REST. It is newer and has better documentation.
I have looked through the laravel-omnipay package and I can't see a use case for it. I would just code to the omnipay package directly.
I recommend that you create a unique transaction ID for each transaction and provide that as part of the URLs for returnUrl and cancelUrl so that you can identify which transaction you are dealing with in the return and cancel handlers.
I think that you are taking the examples in the laravel-omnipay package too literally. You don't need or want those echo statements there. You should be capturing the response from purchase() even if it is a redirectResponse and doing a getTransactionReference() check on it, because you will need that transaction reference later, e.g. for transaction lookup. You should store it in the transaction record that you created before calling purchase().
You may use
use Omnipay\Omnipay;
in your controller, change it to
use Omnipay;

Drupal 7: Show fields on a form based on another field and a database lookup

I have a form I created in a custom module using the Form API. It is a fairly basic form with only 4 fields. It basically signs a user up for a job alert system. We are basing it only by email address with a few search parameters. We want people to be able to setup a search agent quickly and anonymously meaning they will NOT be creating a Drupal user account as we don't want them to have to deal with a password etc. They will just put in their email address, check off a few preferences and we will save the data.
Now the issue I need to deal with is allowing the user to edit their preferences later on and/or unsubscribe. Again this is not high security and it doesn't need to be. What I would like to do is initially ask ONLY for their email address in the form and allow them to submit it. I would then check the database to see if we already have an entry for that email address and if so, display the pre-filled form for them to edit or unsubsribe, other wise just show them the blank form. So I am just trying to figure out the best way to go about this. I'm thinking I just have one form with all of the fields including email address, but somehow only display the other fields besides the email address after a successful call to the database. I'm just tripping up on how to accomplish this.
EDIT:
I'm wondering if I can use Drupal's AJAX functionality to accomplish this? I tried this, but I couldn't get it to work. I put an Ajax attribute on my submit button with a wrapper ID and a callback function. I created a form element in my form with blank markup and used a prefix and suffix that created a wrapper div with the ID I used in my AJAX parameter. Then I am thinking in my callback function I can do the database lookup and then return the form elements I need either pre-filled or not into the wrapper div that was created, but when I do this, the form does submit via AJAX and I get the spinning wheel, but no matter what I return in my callback, it does not appear in my output wrapper div. Am I going about this the right way? I also made sure I have $form_state['rebuild'] = TRUE; on my original form.
Here is what I tried and it didn't work.
/**
* Implements hook_form().
*/
function _vista_form($form, &$form_state) {
$form = array();
$form_state['rebuild'] = TRUE;
$form['email'] = array(
'#type' => 'textfield',
'#title' => 'Email',
'#required' => TRUE,
);
$form['render_area'] = array(
'#type' => 'markup',
'#markup' => '',
'#prefix' => '<div id="job-agent-form">',
'#suffix' => '</div>',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#attributes' => array('class' => array('submit')),
'#ajax' => array(
'callback' => '_display_form',
'wrapper' => 'job-agent-form',
'method' => 'replace',
'effect' => 'fade',
),
return $form;
}
function _display_form($form, &$form_state) {
// there are other form elements that would go here also, I just added two for example
$type_options = array(
'VISTA-HealthCare-Partners-Government' => 'Vista Healthcare Partners',
'International' => 'International Locum Tenens',
'Permanent' => 'Permanent Physician',
'US-Locum-Tenens' => 'US Locum Tenens',
);
$form['job_type'] = array(
'#type' => 'checkboxes',
'#multiple' => TRUE,
'#title' => 'Type of Job',
'#options' => $type_options,
'#empty_option' => 'Choose a placement type',
'#empty_value' => 'all',
//'#default_value' => $type_selected,
);
$form['active'] = array(
'#type' => 'checkbox',
'#title' => 'Subscribe/Unsubscribe',
'#default_value' => 1,
);
return $form;
}
I would go for creating all fields in the form than use hook_form_alter() to hide the unneeded ones with ['#access'] = FALSE.

Setting shipping info in OmniPay

I'm trying to set a shipping info (name,address, email, etc) using OmniPay for PayPal Express.
I've tried adding shipping info in options array in purchase($options) object:
$options = array(
// required fields (username, pass, etc)
// .....
'shippingAddress1' => 'Elm Street'
'shippingCity' => 'Elm',
'shippingPostcode' => '1000'
// etc.
);
I also tried passing this info to CreditCard object:
$card = new Omnipay\Common\CreditCard($card_options);
without any success. The code:
$gateway = GatewayFactory::create('PayPal_Express');
$gateway->setUsername(USERNAME);
$gateway->setPassword(PASS);
$gateway->setSignature(SIGNATURE);
$gateway->setTestMode(true);
$card_options = array(
'shippingAddress1' => 'Elm Street',
'shippingCity' => 'Elm',
'shippingPostcode' => '10000',
'shippingState' => '',
'shippingCountry' => 'NEverland',
'shippingPhone' => '123465789',
'company' => '',
'email' => 'shipping#test.com'
);
$card = new Omnipay\Common\CreditCard($card_options);
$response = $gateway->purchase(
array(
'cancelUrl'=>'http://localhost/laravel_paypal/',
'returnUrl'=>'http://localhost/laravel_paypal/public/paypalexpress_confirm',
'amount' => '0.99',
'currency' => 'USD',
'card' => $card
)
)->send();
How to add shipping info to PayPal Express using OmniPay?
BTW, I'm using Laravel with PayPal Sandbox.
This problem has recently been fixed (https://github.com/adrianmacneil/omnipay/pull/140) so it should now be possible to set shipping info properly.

not getting email for custom field woocommerce

I am using woocommerce (free plugin).. I am trying to add one custom field to the billing fields..
here it is:
// ADDED HOW YOU GOT TO KNOW ABOUT OUR SERVICE FIELD
add_filter( 'woocommerce_checkout_fields' , 'About_Our_Service' );
// Our hooked in function - $fields is passed via the filter!
function About_Our_Service( $fields ) {
$fields['billing']['billing_meat'] = array(
'label' => __('How you Got to Know About Our Service?', 'woocommerce'),
'placeholder' => _x('', 'placeholder', 'woocommerce'),
'required' => false,
'clear' => false,
'type' => 'select',
'options' => array(
'google-ads' => __('Google', 'woocommerce' ),
'google-search' => __('Yahoo', 'woocommerce' ),
'warrior-forum' => __('Bing', 'woocommerce' ),
'facebook' => __('Facebook', 'woocommerce' ),
'other' => __('Other', 'woocommerce' ),
)
);
return $fields;
}
The problem is: I am not getting the value in my mail for the custom field which was added to the billing fields.. Anyone who already used woocommerce can help me on this... ?
I already created some more custom fields which was added to the checkout (BUT these're not added along with the core fields), for these fields i'm able to get values in my mail..
By the ay, i checked this thread: but didn't much info related to mail..
please kindly someone look into this..
For future readers, custom billing/shipping fields are saved as post meta for the order post. So in general, you can retrieve them with the typical WordPress get_post_meta() function.
But in WooCommerce 2.2, you don't need to as you can pass the field name directly to an array of fields that WC will show as a list in the email:
// pre-WooCommerce 2.3
function kia_email_order_meta_keys( $keys ) {
$keys['Some field'] = '_some_field';
return $keys;
}
add_filter('woocommerce_email_order_meta_keys', 'kia_email_order_meta_keys');
This method has been deprecated in version 2.3, probably so translation can be better. As of 2.3 you will need to target a different filter and send slightly different data.
// WooCommerce 2.3+
function kia_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
$fields['some_field'] = array(
'label' => __( 'Some field', 'my-plugin-textdomain' ),
'value' => get_post_meta( $order->id, '_some_field', true );
);
return $fields;
}
add_filter('woocommerce_email_order_meta_fields', 'kia_email_order_meta_keys', 10, 3 );
I wrote a tutorial on Customizing WooCommerce Checkout Fields
I believe this answer, in the codex is specifically meant for this purpose:
http://wcdocs.woothemes.com/snippets/add-a-custom-field-in-an-order-to-the-emails
I haven't implemented this myself but it's probably your best shot.