wordpress - woocommerce- woocommerce_api_authentication_error on api - wordpress

I’m using the woocommerce api for my application, i’ve created the keys and apis and it did work fine , it authenticate and return the data via the api .
It’s been two days that it doesn’t connect any more , I’ve made a new api key but the same result.
I get this message when I run the url :
{"errors":[{"code":"woocommerce_api_authentication_error","message":"\u06a9\u0644\u06cc\u062f \u06cc\u06a9 \u0645\u0646\u0638\u0648\u0631\u0647 \u0646\u0627\u0645\u0639\u062a\u0628\u0631 \u0627\u0633\u062a. \u06a9\u0644\u06cc\u062f \u0642\u0628\u0644\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0634\u062f\u0647 \u0627\u0633\u062a."}]}
it says woocommerce_api_authentication_error , but I've created new keys and I'm sure the keys are correct .
can you help me . this is a sample code of mine :
$options = array(
‘debug’ => true,
‘return_as_array’ => false,
‘validate_url’ => false,
‘timeout’ => 30,
‘ssl_verify’ => false,
);
$client = new WC_API_Client(‘http://nodasht.com’,
“ck_4c25b06d7a9e507fbdeb06e338e20a2db1f7cc43”,
“cs_b89c9152510beb3cd915942cc4f33b91b720d62e”, $options);
$res = $client->products->get($row->ID);
$product = $res->product;

If you google bits of your message like this part \u06a9 you will be able to find out what the message is , thus know what the actual problem is.

Related

Get list of Webhooks from Woocommerce

I have built a Wordpress plugin that among other things, creates several Woocommerce Webhooks upon activation. This is done using internal API classes and functions, as per below:
function createWebhook($userID,$topic,$secret,$deliveryURL,$status)
{
$webhook = new WC_Webhook();
$webhook->set_user_id($userID); // User ID used while generating the webhook payload.
$webhook->set_topic( $topic ); // Event used to trigger a webhook.
$webhook->set_secret( $secret ); // Secret to validate webhook when received.
$webhook->set_delivery_url( $deliveryURL ); // URL where webhook should be sent.
$webhook->set_status( $status ); // Webhook status.
$save = $webhook->save();
return $save;
}
This works well.
What I want to be able to do is remove these Webhooks upon deactivation of the plugin. Is there any way to fetch the Woocommerce Webhooks via the internal Wordpress or Woocommerce API, so I can loop through and remove the relevant ones?
I would just remove all Webhooks where the delivery URL has a domain of xyz.com. This part is straight-forward, I just don't know how to fetch the Webhooks.
I don't want to use the external Woocommerce API, which requires an API key and HTTP requests.
Thanks
I ended up querying the database to get the webhooks, which looks to be working well. I'm not sure there's any other way. Please let me know if there is!
global $wpdb;
$results = $wpdb->get_results( "SELECT webhook_id, delivery_url FROM {$wpdb->prefix}wc_webhooks" );
foreach($results as $result)
{
if(strpos($result->delivery_url, 'domain.com') !== false)
{
$wh = new WC_Webhook();
$wh->set_id($result->webhook_id);
$wh->delete();
}
}
#greg's answer points you in the right direction, but the returned data is just an array of ID's for each webhook, to get more data you need to parse those ID's into webhook objects - which has protected props, but public getter methods, like so:
$data_store = \WC_Data_Store::load( 'webhook' );
$webhooks = $data_store->search_webhooks([ 'status' => 'active', 'paginate' => true ] );
$_items = array_map( 'wc_get_webhook', $webhooks->webhooks );
$_array = [];
foreach( $_items as $_item ){
$_array[] = [
'id' => $_item->get_id(),
'name' => $_item->get_name(),
'topic' => $_item->get_topic(),
'delivery_url' => $_item->get_delivery_url(),
'secret' => $_item->get_secret(),
];
}
You can get an array of all webhook IDs with the following:
$data_store = WC_Data_Store::load( 'webhook' );
$webhooks = $data_store->search_webhooks();
That's what WooCommerce does when building the table list:
https://github.com/woocommerce/woocommerce/blob/master/includes/admin/class-wc-admin-webhooks-table-list.php

wordpress Front End PM

i use the plugin Front End PM
https://he.wordpress.org/plugins/front-end-pm/
And i wonder how can i make an private message throw the PHP code and not as a frontend user , i search all over here and the docs of the plugin and i found out that there is a function call 'fep_save_message' , but with no success on it...
can someone help ? , if you know other plugin that can help me throw code send a private message i want to know .
Thanks :) !
In last project we use BuddyPress and BuddyPress private message https://buddypress.org/about/private-messaging/ this work very nice.
You may try use https://wordpress.org/plugins/wp-recall/ but this is add not only PW.
You can use fep_send_message() function to send message. It supports directly post data or you can pass data as argument.
Example
$message = array(
'message_title' => 'Title of your message',
'message_content' => 'Content of your message',
'message_to_id' => 123, //Receiver id
);
$message_id = fep_send_message( $message );

Funds not getting transferred between paypal sandbox accounts

I am trying to integrate ci-merchant with codeigniter by using paypal express driver. I followed the steps as given in the document. I am able to get my site redirected to paypal sandbox payment site where the Total cost and everything is available. But when I try paying using paypal sandbox account by logging in, it does not show me the paypal balance even though I have enough in my account. When I click pay now, It redirects me to the return url successfully with token and payer ID in the url. But no fund is getting transferred.Not sure where I am going wrong.
url : ../retSuccess?token=EC-01M80248BN787213M&PayerID=9WLBBV9LM6TPA
$this->load->model('mainmodel');
$this->mainmodel->orderDetails();
$query = $this->mainmodel->retrieveOrder();
foreach ($query as $row){
$transaction_id = $row['transaction_id'];
}
$this->load->library('merchant');
$this->merchant->load('paypal_express');
$settings = array(
'username' => 'merchant_api1.canada.com',
'password' => '1369782104',
'signature' =>'AmTaSH3lkRIYxxjxUjB.1zqxD0cRA1hfMGBX2dV9h4DkcYQcjGtqDaYa',
'test_mode' => true);
$this->merchant->initialize($settings);
$params = array(
'amount' => $this->input->post('price'),
'currency' => 'CAD',
'description'=> $this->input->post('model_no'),
'return_url' => base_url('payment/transaction/'.$transaction_id),
'cancel_url'=> base_url('payment/cancel'));
$response = $this->merchant->purchase($params);
}
public function transaction(){
$transaction_id = $this->uri->segment(3);
$this->load->model('mainmodel');
$query = $this->mainmodel->loadTransaction($transaction_id);
foreach ($query as $row){
$price = $row['price'];
$desc = $row['model_no'];
$trans_id = $row['transaction_id'];
}
$this->load->library('merchant');
$this->merchant->load('paypal_express');
$params = array(
'amount' => '21.3',
'currency' => 'CAD',
'description' => 'SP66');
$response = $this->merchant->purchase_return($params);
if ($response->success())
{
$data['gateway_reference'] = $response->reference();
$data['model_no'] = $this->session->userdata('model_no');
$data['category'] = $this->session->userdata('category');
$data['specs'] = $this->session->userdata('specs');
$data['quantity'] = $this->session->userdata('quantity');
$newData = array('status'=>'complete',
'reference'=>$data['gateway_reference']);
$this->db->where('transaction_id',$trans_id);
$this->db->update('transactions',$newData);
$this->load->view('templates/success',$data);
}else{
$data['message'] = $response->message();
//$this->db->where('transaction_id',$trans_id);
//$this->db->delete('transactions');
$this->load->view('templates/failure',$data);
}
}
If I understand you correctly, the sandbox account should have a buy and seller account. You need to check the seller account to see the purchase from the buyer account.
I don't think the problem is from CI Merchant.
Make sure that the CI Merchant is calling PayPal's DoExpressCheckout API. This is the last API call of the Express Checkout, and this is the API that actually completes the payment and transfers the money.
With ci-merchant you need to call purchase_return on your return page to complete the payment, it looks like you just put everything on the initial (pre-paypal) page which won't do anything.

Using token as data selector

I created the following token; however, when I try to use site:coupons as a data selector in a loop action
It does not appear in data selection browser. Note that it does appear as replacement pattern when i use for example "Show a message on the site" action.
I spent lot of time searching in the internet and rules' token' issue queue, i tried to read the source codes of core token , token and rules as well. I also found some information too like data selector are no tokens! or rules only works with entities!
So far i couldn't get this to work no matter hard i tried. My data is not entity. Is there anyway to integrate it with rules?
I couldn't find any official documentation on this so i created an issue with hope that some of the rule's experts can help me out.
Note : if i replace site with coupon-link in the following code, it won't even appear as replacement pattern in rules. but it works fine as token anywhere else but in rules
Thanks in advance
<?php
/**
* Implements hook_token_info().
*/
function coupon_link_token_info() {
$types['coupon-link'] = array(
'name' => t("Coupon link coupon info"),
'description' => t("Info about linked coupon via url."),
);
// Andy Pangus specific tokens.
$tokens['site']['coupon-code'] = array(
'name' => t("Coupon Link Coupon Code"),
'description' => t("The code of the coupon entered via url."),
);
$tokens['site']['coupon'] = array(
'name' => t("Coupon Link Coupon"),
'description' => t("The coupon entered via url."),
'type' => 'commerce_coupon'
);
$tokens['site']['coupons'] = array(
'name' => t("Coupon Link List Coupons"),
'description' => t("The coupons entered via url."),
'type' => 'array'
);
return array(
'types' => $types,
'tokens' => $tokens,
);
}
/**
* Implements hook_tokens().
*
* #ingroup token_example
*/
function coupon_link_tokens($type, $tokens, array $data = array(), array $options = array()) {
$replacements = array();
$sanitize = !empty($options['sanitize']);
// Text format tokens.
if ($type == 'site' && __coupon_link_get_coupon_code()) {
//$format = $data['format'];
foreach ($tokens as $name => $original) {
switch ($name) {
case 'coupon-code':
// Since {filter_format}.format is an integer and not user-entered
// text, it does not need to ever be sanitized.
$replacements[$original] = $sanitize ? filter_xss(__coupon_link_get_coupon_code()) : __coupon_link_get_coupon_code();
break;
case 'coupon':
// Since the format name is user-entered text, santize when requested.
$replacements[$original] = __coupon_link_get_coupon(__coupon_link_get_coupon_code());
break;
case 'coupons':
// Since the format name is user-entered text, santize when requested.
$replacements[$original] = array(__coupon_link_get_coupon(__coupon_link_get_coupon_code()));
break;
}
}
}
return $replacements;
}
?>
A few things.
Tokens are formatted as [type:token] as explained on the hook_token_info api page. For your example, it would be [coupon-link:coupon]. I'm not sure why you're appending your tokens to the site array, as your custom coupon token probably has nothing to do with sitewide tokens like *site_url* or *site_name*.
Because the types are machine names, you should change it to coupon_link as machine names with dashes are not Drupal standard.
If you truly get lost, I suggest also looking at the token example from the examples module.

Multiple concurrent database connections in drupal 7

I'm writing a wrapper class for my drupal 7 site which lets me connect to and query my phpbb database.
When connecting to an external data source (as per drupal documentation) you have set the active db, run the query, then set the active db back to the default.
e.g.
db_set_active('phpbb');
$result = db_query($sql,$args,$opts);
db_set_active();//back to default
But is there any way to use drupal's database wrapper to create a brand new connection which can be permanently set to the new database without having to do this switching back-and-forth nonsense? surely we can handle connections to multiple databases concurrently.
I have done some googling but haven't found anybody trying to do this as yet.
Typical. 5 minutes after posting i figure it out... so, for future googlers:
Basically, you don't use db_query, instead you run the query on your connection without setting the active link.
you can figure this out by looking at how db_query works:
http://api.drupal.org/api/drupal/includes--database--database.inc/function/db_query/7
So it looks like this:
$target='default';
$key = 'phpbb';
$phpbb = Database::getConnection($target,$key);
$result = $phpbb->query($sql,$args,$opts);
This assumes you have a database configured in your settings.php like the following:
$databases['phpbb']['default'] = array(
'driver' => 'mysql',
'database' => 'forum',
'username' => 'username',
'password' => 'password',
'host' => 'mysql.host.com',
'prefix' => 'phpbb3_'
);
Database::addConnectionInfo() perhaps?
This method allows the addition of new connection credentials at
runtime. Under normal circumstances the preferred way to specify
database credentials is via settings.php. However, this method allows
them to be added at arbitrary times, such as during unit tests, when
connecting to admin-defined third party databases, etc.
If the given key/target pair already exists, this method will be
ignored.
The definition for getConnection cites a different order for arguments than used above.
function getConnection($target = 'default', $key = NULL)
This is sadly different from Database::addConnectionInfo() which is
public static function addConnectionInfo($key, $target, $info)
Also, on DB_select, the $key is not a parameter, though it is in the options array:
function db_select($table, $alias = NULL, array $options = array()) {
if (empty($options['target'])) {
$options['target'] = 'default';
}
return Database::getConnection($options['target'])->select($table, $alias, $options);
}
while
final public static function getConnection($target = 'default', $key = NULL) {
so this implies that the 'master' or 'slave' or 'default' is always used as set, but not the key to the alternative database/schema, requiring the db_set_active('...'); and db_set_active(); around the db_select.
Since calls to other dbs can easily be required within the processing of the db_select (such as devel calls or calls in alters), this is inflexible design. Changing this call:
return Database::getConnection($options['target'])->select($table, $alias, $options);
to add the Key parameter (it is already spec'd as an argument!!) is needed but insufficient so far as I can now see.

Resources