Paypal PHP checkout - php

I have this code below, it works perfectly, but I can use a proxy to change all the data (I also can change the receiver email) :/
How can I make it a POST checkout method? Now it's a GET method
<?php
public function checkout()
{
$query = [];
$query['cmd'] = '_cart';
$query['upload'] = 1;
$query['business'] = $this->getCredential();
foreach ($this->getItems() as $id => $item)
{
$id = $id + 1;
$query['item_name_' . $id] = $item['name'];
$query['amount_' . $id] = $item['amount'];
$query['quantity_' . $id] = $item['quantity'];
}
$query['custom'] = $this->getReference();
$query['<first_name>'] = $this->first_name;
$query['<last_name>'] = $this->last_name;
$query['<email>'] = $this->customer_email;
$query['notify_url'] = $this->getNotificationURL();
$query['return'] = $this->getReturnURL();
$query['cancel_return'] = $this->getCancelURL();
$query['rm'] = '2';
$query['cbt'] = 'Retornar para o site';
$query['lc'] = $this->getLocation();
$query['currency_code'] = $this->getCurrency();
$query_string = http_build_query($query);
return "https://". ($this->isSandbox() ? 'sandbox' : 'www' ) .".paypal.com/cgi-bin/webscr?".$query_string;
}
I also tried the code below, but when I click to finish the payment, it return me to the return URL with the token and payer_id, but don't pay :C
public function checkout()
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://api-m.paypal.com/v2/checkout/orders');
curl_setopt($curl, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: ' . $this->getAccessToken(),
'Prefer: return=representation'
]);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode([
'brand_name' => 'yStore Plugins',
'intent' => 'CAPTURE',
'purchase_units' => $this->getItems(),
'application_context' => [
'notify_url' => $this->getNotificationURL(),
'cancel_url' => $this->getCancelURL(),
'return_url' => $this->getReturnURL()
]
]));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($curl));
curl_close($curl);
return $response->links[1]->href;
}

Follow the Set up standard payments guide which in its 'Add and modify the code' section explains that you should make 2 routes on your server, one for 'Create Order' and one for 'Capture Order', documented here. For PHP you can use the Checkout-PHP-SDK (not any older or deprecated SDK). When accessed by a browser, both routes you create should only output JSON data (no additional HTML or text which cannot be parsed as JSON). Inside the 2nd route, when the capture API is successful you should store its resulting payment details in your database (particularly purchase_units[0].payments.captures[0].id, which is the PayPal transaction ID) and perform any necessary business logic (such as sending confirmation emails or reserving product) immediately before forwarding your return JSON to the frontend caller.
Pair those 2 routes with the frontend approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server , which has important client-side error handling.

Related

Change Slack Bot Icon from Post PHP

We post a message to a slack channel every time a customer does a specific task. We want to change the bot Icon based on what is being posted in the channel.
Is this possible?
public static function send_to_slack($message,$title = null){
$body = array();
$body['text'] = '';
$body['icon_url'] = '';
if(!empty($title)) $body['text'] .= "*$title*\n";
$body['text'] .= $message;
$iconURL = "https://img.icons8.com/emoji/96/000000/penguin--v2.png";
$body['icon_url'] .= $iconURL;
$json = json_encode($body);
//Test Slack Channel
$slack = "SLACKURL"
$response = wp_remote_post( $slack, array(
'method' => 'POST',
'body' => $json,
)
);
if ( is_wp_error( $response ) ) {
return true;
} else {
return true;
}
}
From Slack:
You cannot override the default channel (chosen by the user who installed your app), username, or icon when you're using Incoming Webhooks to post messages. Instead, these values will always inherit from the associated Slack app configuration.
*** UPDATE
I just ran into this situation. My old app was using the old web hooks. I had to create a new integration and ran into this issue. The simple solution is to install the slack app called "Incoming Webhooks". It's made by slack. It will allow you to generate an older style webhook that will allow you to post to any channel.
Found the correct way. Make sure you enable chat:write.customize in Slack oAuth Scope.
public static function send_to_slack($message,$title = null){
$ch = curl_init("https://slack.com/api/chat.postMessage");
$data = http_build_query([
"token" => "BOT-TOKEN",
"channel" => "CHANNELID", //"#mychannel",
"text" => $message, //"Hello, Foo-Bar channel message.",
"username" => "MySlackBot",
"icon_url" => $iconURL
]);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}

Why is HubSpot Autogenerating Forms?

I am submitting a contact form to HubSpot using their api (https://developers.hubspot.com/docs/methods/forms/submit_form), which is working out great, except that every time I do it, HubSpot autogenerates a new form in its site under Marketing -> Forms, with a name like #form_5dd7ee368739f. It says that this is a non-Hubspot form and gives this explanation:
What is a non-HubSpot form
Non-HubSpot forms are HTML forms on your
website that weren't created in HubSpot. Based on your settings,
data for these forms is automatically collected in HubSpot. Learn
more.
"Learn more" isn't a link; I can't click on it. The submission of the api request is recorded both in this new form that it autogenerated each time the form is submitted, as well as in the form that I built in HubSpot that supposed to handle this request. Here is my code:
<?php
// wp-config.php
define('HUBSPOT_PORTAL_ID', getenv('hubspot_portal_id'));
define('HUBSPOT_CONTACT_FORM_GUID', getenv('hubspot_contact_form_guid'));
define('HUBSPOT_CONTACT_FORM_ENDPOINT', "https://forms.hubspot.com/uploads/form/v2/".HUBSPOT_PORTAL_ID."/{form_guid}");
?>
<?php
// hubspot.php
function hubspot_form_submit($page_url, $page_name, $endpoint, $data) {
$hs_context = array(
'ipAddress' => $_SERVER['REMOTE_ADDR'],
'pageUrl' => $page_url,
'pageName' => $page_name,
);
if (array_key_exists('hubspotutk', $_COOKIE)) {
$hs_context['hutk'] = $_COOKIE['hubspotutk'];
}
$data['hs_context'] = $hs_context;
$data_string = "";
foreach ($data as $key => $value) {
if (is_string($value)) {
$value = urlencode($value);
}
else if (is_array($value)) {
$value = json_encode($value);
}
$data_string = $data_string.$key."=".$value."&";
}
$data = rtrim($data_string, "&");
$ch = #curl_init();
#curl_setopt($ch, CURLOPT_POST, true);
#curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
#curl_setopt($ch, CURLOPT_URL, $endpoint);
#curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded'
));
#curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = #curl_exec($ch);
if(curl_error($ch)) {
$result = curl_error($curl);
}
$status_code = #curl_getinfo($ch, CURLINFO_HTTP_CODE);
#curl_close($ch);
return $result;
}
?>
<?php
// contact.php
require_once("inc/hubspot.php");
$hubspot_form_submission = hubspot_form_submit(
"https://www.example.com/contact/",
"Contact",
str_replace("{form_guid}", HUBSPOT_CONTACT_FORM_GUID, HUBSPOT_CONTACT_FORM_ENDPOINT),
array(
"firstname" => $form->data["first_name"],
"lastname" => $form->data["last_name"],
"email" => $form->data["email"],
"phone" => $form->data["phone"],
"preferred_contact_method" => $form->data["contact_method"],
"message" => $form->data["comments"],
)
);
?>
Anyone know how I can prevent HubSpot from autogenerating these forms? Otherwise my forms box will quickly become filled up with hundreds of autogenerated forms that I will keep having to delete. Something to note: the actual form that I created for this purpose is located within a folder, whereas the autogenerated forms are always located outside of any folders, if that makes any difference.
Found the problem: the client had enabled the use of Non-HubSpot forms in their settings, so all that is required to fix it is just to turn this functionality off. The documentation is here:
https://knowledge.hubspot.com/forms/use-non-hubspot-forms
The setting is located in
Settings -> Marketing -> Forms -> Non-HubSpot Forms

How to use JSON and HTTP POST in Laravel to work with a ticketing API

I'm trying to implement a JSON payload to create a ticket using HTTP POST and this API(https://github.com/osTicket/osTicket/blob/develop/setup/doc/api.md) in my PHP application (using Laravel framework) and I'm at an utter loss as to how to start attacking this problem. any insight?
I currently have a form built with laravel that will collect user data through a form. My goal is to take the data from said form, populate the fields on a JSON payload (the one I have below is from the API's github page) and then submit the ticket to the system when the "submit form" button is hit. Literally any help at all or advice would be greatly appreciated
This is what the JSON payload would look like but I also don't know where in laravel to put it/how to format it.
{
"alert": true,
"autorespond": true,
"source": "API",
"name": "Angry User",
"email": "randoemail#gmail.com",
"phone": "3333333333",
"subject": "Testing API",
"ip": "123.211.233.122",
"message": "data:text/html,MESSAGE <b>HERE</b>",
}
You can try it like so (No other stuff required):
Create an osTicket lib somewhere (I've placed it in app/Library)
namespace App\Library;
class osTicket {
protected $url;
protected $apikey;
protected $topicid;
public function __construct($apikey = null, $url = null, $ip = null) {
$this->url = env('TICKET_URL', $url);
$this->apikey = env('TICKET_APIKEY', $apikey);
$this->ip = env('TICKET_IP', $ip);
}
public function createTicket($name, $email, $phone, $subject, $message) {
$data = array(
'name' => $name,
'email' => $email,
'phone' => $phone,
'subject' => $subject,
'message' => $message,
'ip' => $this->ip,
[whatever other stuff you've configured in your OSticket, e.g. product_id, list_id, etc. - just pass appropriate variable]
);
function_exists('curl_version') or die('CURL support required');
function_exists('json_encode') or die('JSON support required');
set_time_limit(30);
$ch = curl_init();
//not everything below is needed. depends on you
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_USERAGENT, 'osTicket API Client v1.8');
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Expect:', 'X-API-Key: '.$this->apikey));
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $result;
}
}
Setup your variables in .env:
TICKET_URL=http://xxxxxxxx.com/api/http.php/tickets.json
TICKET_APIKEY={api_key_here}
TICKET_IP={your_ip}
Then pass along form post data to your Controller like so:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Library\osTicket;
use Auth;
use User;
class WhateverController extends Controller {
public function addticket(Request $request) {
$user = User::find(Auth::id());
$ticket = new osTicket;
$ticket->createTicket($user->name, $user->email, $user->phone, $request->subject, $request->message);
if($result === true) {
return back();
} else {
return back()->with('status', $result);
}
}
}
What you're looking to do should work by going through two steps
Build a PHP dict/array with the desired values, then (depending on the HTTP library - see below) convert that to JSON. Something like this in your controller method:
$dict['alert'] = $request->input('alert');
$dict['autorespond'] = $request->input('autorespond');
...
$json = json_encode($dict);
Alternaively if there is no content that should not be posted to the API you can do:
$json = json_encode($request->all());
See: https://laravel.com/docs/5.4/requests and http://us1.php.net/manual/en/function.json-encode.php
Once you have your json you need an http library to perform the request. Laravel recommends Guzzle so you would do something like:
$client = new GuzzleHttp\Client(['base_uri' => 'https://github.com.com/whatever/']);
$response = $client->post('the/api/endpoint', ['json' => $request->all()]);
Note that you don't need to json_encode the content here as Guzzle will do that for you.
See: http://docs.guzzlephp.org/en/latest/quickstart.html
From there handle the data however you need.

How to update segments and groups of an existing subscriber in MailChimp API 3

Iv'e written a method to subscribe users to MailChimp. Whats 'special' about it is that it automatically subscribe the users to groups within the list, and segments within the list, based on the users' cart items, wishlist items, and the item and / or category that he has subscribed from.
The integration with MailChimp is straight forward - I get the data > send curl > get response > handle response.
I'm looking for a way to constant update the users' groups and segments, based on their actions in my store.
Now, the only accepted statuses MailChimp can get are 'subscribed', 'pending', and 'clean'. All of them aren't updating, only inserting new subscribers. If the email is already subscribed, nothing is being updated, not even data that is different than what the subscriber has in its profile in my MailChimp lists.
Here's my code for reference:
protected static function subscribeToMailchimp($email, $fullname)
{
$params = EkerbaseJoomla::getPluginParams('system', 'ekerbaseusers');
$interests = self::getUserInterestsObject();
$apikey = $params->mailChimpApiKey;
$listId = $params->mailChimpListId;
$interestCategoryId = $params->mailChimpInterestCategoryId;
$auth = base64_encode( 'user:' . $apikey );
$apiUrl = 'https://'.substr($params->mailChimpApiKey, -3).'.api.mailchimp.com/3.0/lists/'.$listId;
$possibleGroups = json_decode(file_get_contents($apiUrl . '/interest-categories/' . $interestCategoryId . '/interests?apikey=' . $apikey))->interests;
$segments = json_decode(file_get_contents($apiUrl . '/segments?apikey=' . $apikey))->segments;
$data = [
'apikey' => $apikey,
'email_address' => $email,
'status' => 'subscribed',
'merge_fields' =>
[
'FNAME' => $fullname
]
];
if( ! empty($interests->categories) ) {
$data['interests'] = [];
foreach( $possibleGroups as $group ) {
if( in_array($group->name, $interests->categories) ) {
$data['interests'][$group->id] = true;
}
}
}
if( ! empty($interests->items) ) {
$data['segments'] = [];
foreach( $segments as $segment ) {
if( in_array($segment->name, $interests->items) ) {
$data['segments'][$segment->id] = true;
}
}
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl . '/members/');
curl_setopt($ch, CURLOPT_HTTPHEADER,
[
'Content-Type: application/json',
'Authorization: Basic '.$auth
]
);
curl_setopt($ch, CURLOPT_USERAGENT, 'PHP-MCAPI/3.0');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$result = curl_exec($ch);
$response = json_decode($result);
switch( $response->status ) {
case 'subscribed':
$responseMessage = JText::_('EKERBASE_SUCCESS_NEWSLETTER');
$responseStatus = 'success';
$responseResult = 'mailchimp subscribing succeeded';
break;
default:
$responseStatus = 'error';
$responseMessage = $response->title;
$responseResult = 'mailchimp subscribing failed';
if( $response->title === 'Member Exists' ) {
$responseMessage = JText::_('EKERBASE_NEWSLETTER_ALREADY_SUBSCRIBER');
}
break;
}
return EkerbaseAjax::buildJsonResponse($responseMessage, $responseStatus, $responseResult);
}
If your integration is adding entirely new subscriber as expected, and the issue appears isolated to cases where the method is updating an existing sub's record, the issue may pertain to the HTTP method, and/or the api endpoint.
As v3 of MailChimp's API only allows subscribers to be initialized when using the POST method(which looks like it may be hard coded into cURL here), and is likely why entirely new subscribers are being added without issue.
This said, when wanting to add or update new subscribers using PUT would be recommended, and is specified in their docs.
Add or update a list member
more on http methods and their API
Additionally, along with this alternate method usage, to ensure existing subscribers are updated, you'll also need to append the MD5 hash of the lower case version of their email to to the endpoint. This only needs to be done for existing subs.
e.g. /members/{lowercase_email_MD5_hash}
Which should be provided in the response if you're first checking with MailChimp whether or not a subscriber exist, if you'd like to recycle that.

Yii2 request PUT not working properly

I am using a rest api in yii2 with Authorization : Bearer and my update action requires sending data using PUT. I have configured the actionUpdate completely but somehow i am not getting any data in Request PUT.
I found few articles online about problems with Yii2 PUT but could not find out weather there is any solution to that yet or not?
One of the article or issue is github issue and it points to this github issue
Ad if no solution yet than what alternative should i use for Update action.
Here is my actionUpdate code
public function actionUpdate($id)
{
$params = Yii::$app->request->bodyParams;
$model = Event::find()->where(['event_id'=>$id])->andWhere(['partner_id' => Yii::$app->user->id])->one();
if($model !== null){
$model->load($params, '');
$model->partner_id = Yii::$app->user->id;
$model->updated_date = time();
if ($model->save()) {
$this->setHeader(200);
echo json_encode(array('status'=>1,'data'=>array_filter($model->attributes)),JSON_PRETTY_PRINT);
}
}
}
This is a screenshot of debug screen. See the event_name attribute.
That was screenshot after the execution of $model->load($params,'') line.
I am calling the service like following and not able to Update the data properly. My service works fine through postman.So i guess i am missing something in CURL request.
$service_url = 'http://localhost/site-api/api/web/v1/events/'.$eventDetailDBI->gv ('id');
$curl = curl_init($service_url);
$curl_post_data = array(
"event_name" => $eventDetailDBI->gv ('name'),
);
$header = array();
$header[] = 'Authorization: Bearer 4p9mj82PTl1BWSya7bfpU_Nm';
$header[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER,$header);
curl_setopt($curl, CURLOPT_PUT, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $curl_post_data);
$curl_response = curl_exec($curl);
$json = json_decode($curl_response, true);
curl_close($curl);
I am getting correct data in my POST fields and passing correct data but the service doesnt update any data.
Thank you
try this:
public function actionUpdate($id)
{
// this will get what you did send as application/x-www-form-urlencoded params
// note that if you are sending data as query params you can use Yii::$app->request->queryParams instead.
$params = Yii::$app->request->bodyParams;
$model = Event::find()->where(['event_id'=>$id])->andWhere(['partner_id' => Yii::$app->user->id])->one();
if($model !== null){
// This will load data to your safe attribute as defined in your model rules using your default scenario.
$model->load($params, '');
$model->partner_id = Yii::$app->user->id;
$model->updated_date = time();
if ($model->save()) {
/*
you can use Yii::$app->getResponse()->setStatusCode(200) here but no need to do that.
response will be 200 by default as you are returning data.
*/
// yii\rest\Serializer will take care here of encoding model's related attributes.
return [
'status' => 1,
'data' => $model
];
}
else {
// when validation fails. you model instance will hold error messages and response will be auto set to 422.
return $model;
}
}
}

Categories