Wondered if anyone could give me any pointers?
The website I'm currently building sells 'event' tickets....holidays.
What I'm trying to do is decrease the number of tickets in a database field by the number purchased BUT can't find a paypal cart variable which will pull the information back. The custom variable it seems can only be used once and the item_name and item_number variables are already being used, the (item_number) to identify the 'event_id' field in the database and the (item_name) to obviously identify the event name.
I can pass the correct number of tickets to be updated over to Paypal by decreasing the amount and echoing that out in a hidden form field prior to sumbitting to Paypal BUT I can't get the results back. I'm looking for a Paypal form 'name' field that can be adapted to my needs, if one exists
Below is the database loop: The 'custom' variable doesn't work as it can't be custom1, custom2 etc.
mysql_connect('xxxxxxxx', 'xxxxxx', 'xxxxxxxx') or exit(0);
mysql_select_db('xxxxxx') or exit(0);
$num_cart_items = $_POST['num_cart_items'];
$i=1;
while (isset($_POST['item_number'.$i]))//read the item details
{
$item_ID[$i]=$_POST['item_number'.$i];
$custom[$i]=$_POST['custom'.$i];
$i++;
}
$item_count = $i-1;
for ($j=1;$j<=$item_count;$j++)
{
$struery = "UPDATE events SET event_tickets = '".$custom[$j]."' WHERE event_id = '".$item_ID[$j]."'";
$result = mysql_query($struery) or die("Cart - paypal_cart_info, Query failed:<br>" . mysql_error() . "<br>" . mysql_errno());
$i++;
}// end database loop
Thanks for any info.
Os
You can put custom variable as JSON encoded string. Then decode it.
$i=1;
$custom = json_decode($_POST['custom], TRUE);
while (isset($_POST['item_number'.$i]))//read the item details
{
$item_ID[$i] = $_POST['item_number'.$i];
$custom[$i] = $custom[$i];
$i++;
}
Or you can even base64_encode it on send to paypal and верут decode it back it you want variable not to be readable when you redirect user to paypal.
Related
I have this code
$product_info = array();
if(isset($cms['site']['url_data']['product_id'])){
$product_info = $cms['class']['product']->get($cms['site']['url_data']['product_id']);
}
if(!isset($product_info['id'])){
/*
echo 'No product info.';
exit();
*/
header_url(SITE_URL.'?subpage=user_subscription#xl_xr_page_my%20account');
}
$fee = $product_info['yearly_price_end'] / 100 * $product_info['fee'];
$yearly_price_end = $product_info['yearly_price_end'] + $fee;
$fee = ($product_info['setup_price_end'] / 100) * $product_info['fee'];
$setup_price_end = $product_info['setup_price_end'] + $fee;
if(isset($_SESSION['discountcode_amount'])){
$setup_price_end = $setup_price_end - $_SESSION['discountcode_amount'];
unset($_SESSION['discountcode_amount']);
}
$error = false;
$plan_id = '';
$approvalUrl = '';
$ReturnUrl = SITE_URL.'payment/?payment_type=paypal&payment_page=process_agreement';
$CancelUrl = SITE_URL.'payment/?payment_type=paypal&payment_page=cancel_agreement';
$now = $cms['date'];
$now->modify('+5 minutes');
$apiContext = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
$cms['options']['plugin_paypal_clientid'], // ClientID
$cms['options']['plugin_paypal_clientsecret'] // ClientSecret
)
);
use PayPal\Api\ChargeModel;
use PayPal\Api\Currency;
use PayPal\Api\MerchantPreferences;
use PayPal\Api\PaymentDefinition;
use PayPal\Api\Plan;
use PayPal\Api\Patch;
use PayPal\Api\PatchRequest;
use PayPal\Common\PayPalModel;
use PayPal\Api\Agreement;
use PayPal\Api\Payer;
use PayPal\Api\ShippingAddress;
// Create a new instance of Plan object
$plan = new Plan();
// # Basic Information
// Fill up the basic information that is required for the plan
$plan->setName($product_info['name'])
->setDescription($product_info['desc_text'])
->setType('fixed');
// # Payment definitions for this billing plan.
$paymentDefinition = new PaymentDefinition();
// The possible values for such setters are mentioned in the setter method documentation.
// Just open the class file. e.g. lib/PayPal/Api/PaymentDefinition.php and look for setFrequency method.
// You should be able to see the acceptable values in the comments.
$setFrequency = 'Year';
//$setFrequency = 'Day';
$paymentDefinition->setName('Regular Payments')
->setType('REGULAR')
->setFrequency($setFrequency)
->setFrequencyInterval("1")
->setCycles("999")
->setAmount(new Currency(array('value' => $yearly_price_end, 'currency' => $cms['session']['client']['currency']['iso_code'])));
// Charge Models
$chargeModel = new ChargeModel();
$chargeModel->setType('SHIPPING')
->setAmount(new Currency(array('value' => 0, 'currency' => $cms['session']['client']['currency']['iso_code'])));
$paymentDefinition->setChargeModels(array($chargeModel));
$merchantPreferences = new MerchantPreferences();
// ReturnURL and CancelURL are not required and used when creating billing agreement with payment_method as "credit_card".
// However, it is generally a good idea to set these values, in case you plan to create billing agreements which accepts "paypal" as payment_method.
// This will keep your plan compatible with both the possible scenarios on how it is being used in agreement.
$merchantPreferences->setReturnUrl($ReturnUrl)
->setCancelUrl($CancelUrl)
->setAutoBillAmount("yes")
->setInitialFailAmountAction("CONTINUE")
->setMaxFailAttempts("0")
->setSetupFee(new Currency(array('value' => $setup_price_end, 'currency' => $cms['session']['client']['currency']['iso_code'])));
$plan->setPaymentDefinitions(array($paymentDefinition));
$plan->setMerchantPreferences($merchantPreferences);
// ### Create Plan
try {
$output = $plan->create($apiContext);
} catch (Exception $ex){
die($ex);
}
echo $output->getId().'<br />';
echo $output.'<br />';
Been working with paypal php sdk for some days now and my code stop working.
So i went back to basic and i am still getting the same damn error.
I am trying to create a plan for subscription but getting the following error:
"NotifyUrl is not a fully qualified URL"
I have no idea how to fix this as i dont use NotfifyUrl in my code?
Could be really nice if anyone had an idea how to fix this problem :)
Thanks
PayPal did a update to their API last night which has caused problem within their SDK.
They are sending back null values in their responses.
I MUST stress the error is not on sending the request to PayPal, but on processing their response.
BUG Report : https://github.com/paypal/PayPal-PHP-SDK/issues/1151
Pull Request : https://github.com/paypal/PayPal-PHP-SDK/pull/1152
Hope this helps, but their current SDK is throwing exceptions.
Use below simple fix.
Replace below function in vendor\paypal\rest-api-sdk-php\lib\PayPal\Api\MerchantPreferences.php
public function setNotifyUrl($notify_url)
{
if(!empty($notify_url)){
UrlValidator::validate($notify_url, "NotifyUrl");
}
$this->notify_url = $notify_url;
return $this;
}
If you get the same error for return_url/cancel_url, add the if condition as above.
Note: This is not a permanent solution, you can use this until getting the update from PayPal.
From the GitHub repo for the PayPal PHP SDK, I see that the error you mentioned is thrown when MerchantPreferences is not given a valid NotifyUrl. I see you're setting the CancelUrl and ReturnUrl, but not the NotifyUrl. You may simply need to set that as well, i.e.:
$NotifyUrl = (some url goes here)
$obj->setNotifyUrl($NotifyUrl);
Reason behind it!
error comes from.
vendor\paypal\rest-api-sdk-php\lib\PayPal\Validation\UrlValidator.php
line.
if (filter_var($url, FILTER_VALIDATE_URL) === false) {
throw new \InvalidArgumentException("$urlName is not a fully qualified URL");
}
FILTER_VALIDATE_URL: according to this php function.
INVALID URL: "http://cat_n.domain.net.in/"; // IT CONTAIN _ UNDERSCORE.
VALID URL: "http://cat-n.domain.net.in/"; it separated with - dash
here you can dump your url.
vendor\paypal\rest-api-sdk-php\lib\PayPal\Validation\UrlValidator.php
public static function validate($url, $urlName = null)
{
var_dump($url);
}
And then check this here: https://www.w3schools.com/PHP/phptryit.asp?filename=tryphp_func_validate_url
you can check here what character will reason for invalid.
I am working on a project to pull details from state reports on restaurant inspections. Each inspection has its own url. I am able to gather the values into a dictionary, but only return one at a time. In the call to the function, if I don't specify a specific library entry, I get an error: ''list' object has no attribute 'timeout'' If it ask for a specific entry, I get a good return. How can I get them all?
# loop through the url list to gather inspection details
detailsLib = {}
def get_inspect_detail(urlList):
html = urlopen(urlList)
soup = bs4.BeautifulSoup(html.read(), 'lxml')
details = soup.find_all('font', {'face': 'verdana'})[10:]
result = []
for detail in details:
siteName = details[0].text
licNum = details[2].text
siteRank = details[4].text
detailsLib = {
'Restaurant': siteName,
'License': licNum,
'Rank': siteRank,
}
result.append(detailsLib)
return result
get_inspect_detail(urlList[21])
So I can get the 21st restaurant on the list, repeating 36 times, but not all of them.
Another question for another day is where to do the clean-up. The details will need some regex work but I'm unsure whether to do that inside the function (one at a time), or outside the function by calling all values from a specific key in the library.
Call get_inspect_detail() once per item in urlList, and save all the results.
all_results = []
for url in urlList:
details = get_inspect_detail(url)
all_results.extend(details)
I'm already in love with the Custom Fields feature in Trello. Is there a way to get and set custom fields via the API?
I tried using the get field API call to get a field (on a board with a custom field defined called "MyCustomField"):
curl "https://api.trello.com/1/cards/57c473503a5ef0b76fddd0e5/MyCustomField?key=${TRELLO_API_KEY}&token=${TRELLO_OAUTH_TOKEN}"
to no avail.
The Custom Fields API from Trello is now officially available (announcement blog post here).
It allows users to manipulate both custom field items of boards and custom field item values on cards.
Custom Fields API documentation
Getting customFieldItems For Cards
Setting & Updating CustomFieldItems
This is just to add to bdwakefield's answer. His solution involves hard coding the names of the field ids.
If you want to also retrieve the name of the fields themselves (for example get that "ZIn76ljn-4yeYvz" is actually "priority" in Trello, without needing to hard code it, call the following end point:
boards/{trello board id}/pluginData
This will return an array with the plugins information and in one of the array items, it will include a line along the lines of:
[value] => {"fields":[{"n":"~custom field name~:","t":0,"b":1,"id":"~custom field id that is the weird stuff at the card level~","friendlyType":"Text"}]}
So you just need to figure out the plugin for custom fields in your case, and you can retrieve the key -> value pair for the custom field name and the id associated with it.
It means that if you add / remove fields, or rename them, you can handle it at run time vs changing your code.
This will also give you the options for the custom field (when it is a dropdown like in bdwakefield's example above).
So I have a "sort of" answer to this. It requires some hackery on your part to make it work and there is more than a little manual upkeep as you add properties or values -- but it works.
I am doing this in powershell (I am NOT well versed in ps just yet and this my first really 'big' script that I have pulled together for it) since my intent is to use this with TFS Builds to automate moving some cards around and creating release notes. We are using custom fields to help us classify the card and note estimate/actual hours etc. I used this guys work as a basis for my own scripting. I am not including everything but you should be able to piece everything together.
I have left out everything with connecting to Trello and all that. I have a bunch of other functions for gettings lists, moving cards, adding comments etc. The ps module I linked above has a lot of that built in as well.
function Get-TrelloCardPluginData
{
[CmdletBinding()]
param
(
[Parameter(Mandatory,ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[Alias('Id')]
[string]$CardId
)
begin
{
$ErrorActionPreference = 'Stop'
}
process
{
try
{
$uri = "$baseUrl/cards/$CardId/pluginData?$($trelloConfig.String)"
$result = Invoke-RestMethod -Uri $uri -Method GET
return $result
}
catch
{
Write-Error $_.Exception.Message
}
}
}
You'll get data that looks like this:
#{id=582b5ec8df1572e572411513; idPlugin=56d5e249a98895a9797bebb9;
scope=card; idModel=58263201749710ed3c706bef;
value={"fields":{"ZIn76ljn-4yeYvz":2,"ZIn76ljn-c2yhZH":1}};
access=shared}
#{id=5834536fcff0525f26f9e53b; idPlugin=56d5e249a98895a9797bebb9;
scope=card; idModel=567031ea6a01f722978b795d;
value={"fields":{"ZIn76ljn-4yeYvz":4,"ZIn76ljn-c2yhZH":3}};
access=shared}
The fields collection is basically key/pair. The random characters correspond to the property and the value after that is what was set on the custom property. In this case it is an 'index' for the value in the dropdown. These two fields have a 'priority' (low, medium, high) and a 'classification' (Bug, Change Request, etc) for us. (We are using labels for something else).
So you'll have to create another fucntion where you can parse this data out. I am sure there are better ways to do it -- but this is what I have now:
function Get-TrelloCustomPropertyData($propertyData)
{
$data = $propertyData.Replace('{"fields":{', '')
$data = $data.Replace('}}', '')
$data = $data.Replace('"', '')
$sepone = ","
$septwo = ":"
$options = [System.StringSplitOptions]::RemoveEmptyEntries
$obj = $data.Split($sepone, $options)
$cardCustomFields = Get-TrelloCustomFieldObject
foreach($pair in $obj)
{
$field = $pair.Split($septwo,$options)
if (-Not [string]::IsNullOrWhiteSpace($field[0].Trim()))
{
switch($field[0].Trim())
{
'ZIn76ljn-4yeYvz' {
switch($field[1].Trim())
{
'1'{
$cardCustomFields.Priority = "Critical"
}
'2'{
$cardCustomFields.Priority = "High"
}
'3'{
$cardCustomFields.Priority = "Medium"
}
'4'{
$cardCustomFields.Priority = "Low"
}
}
}
'ZIn76ljn-c2yhZH' {
switch($field[1].Trim())
{
'1'{
$cardCustomFields.Classification = "Bug"
}
'2'{
$cardCustomFields.Classification = "Change Request"
}
'3'{
$cardCustomFields.Classification = "New Development"
}
}
}
'ZIn76ljn-uJyxzA'{$cardCustomFields.Estimated = $field[1].Trim()}
'ZIn76ljn-AwYurD'{$cardCustomFields.Actual = $field[1].Trim()}
}
}
}
return $cardCustomFields
}
Get-TrelloCustomFieldObject is another ps function that I set up to build an object based on the properties I know that I have defined.
function Get-TrelloCustomFieldObject
{
[CmdletBinding()]
param()
begin
{
$ErrorActionPreference = 'Stop'
}
process
{
$ccf = New-Object System.Object
$ccf | Add-Member -type NoteProperty -name Priority -value "None"
$ccf | Add-Member -type NoteProperty -name Classification -value "None"
$ccf | Add-Member -type NoteProperty -name Estimated -value ""
$ccf | Add-Member -type NoteProperty -name Actual -value ""
return $ccf
}
}
I have many websites that use some of the same content snippets and instead of manually updating all the different websites, I thought it would be a good idea to have the content stored in a database as to only have one copy instead of multiple. It works great except for one issue which is the images that are in the article are sometimes left aligned and other times right aligned.
My solution was to add the following code to the article's image CSS tag that is in the database and use a variable on each of the individual pages to add the custom classes to the image.
class="<?php echo $ImgClass01; ?>"
EDIT: here is more of the content from what is stored in the database field to make my question a little more understandable.
<p><img src="img/charleston.jpg" class="<?php echo $ImgClass01; ?>">Is it the delightful year-round climate? The almost-European feel of its downtown city streets? The overwhelming...</p>
However, the webpage is only showing the text when viewing the source code and not using the variable. Almost anything is possible, but I'm not sure how to make this work.
Here is the code on the page...
// value for the class within the article to be printed on the page
$ImgClass01 = 'img-responsive img-rounded pull-right';
//Start a while loop to process all the rows
while ($row = mysql_fetch_assoc ($result_set))
{
$article = $row['article'];
echo $article;
} //END WHILE
EDIT: Just in case the entire page will be helpful, here is it.
<?php
$PageTitle = "Charleston, South Carolina | Local Towns";
$PageDescription = "Charleston is rated the first most popular vacation destination in the United States, and it surely must rank in...";
// 1. Create a database connection
$link = mysql_connect ("localhost", "root", "");
if (!$link) die("Could not connect: " . mysql_error());
// 2. Select a database to use
if (!mysql_select_db ("articleBank"))
die("Problem with the database: " . mysql_error());
// 3. Set up query for items to display
$query = "SELECT article FROM `articles` WHERE ID = 1";
// 4. Execute the query
$result_set = mysql_query ($query);
include ("theme/header.php");
// value for the class within the article to be printed on the page
$ImgClass01 = 'img-responsive img-rounded pull-right';
//Start a while loop to process all the rows
while ($row = mysql_fetch_assoc ($result_set))
{
$article = $row['article'];
echo $article;
} //END WHILE
// 5. Close Connection
mysql_close();
include ("theme/footer.php");
?>
while ($row = mysql_fetch_assoc ($other_result_set))
{
$ImgClass01 = $row['ImgClass01'];
}
not sure what you wanted, but you could use left, right in some row like place..
I use Shipworks 3 with Magento 1.5.1 and would like to pass the Purchase order NUMBER through. Right now the Payment Type comes through but I need the PO number so it can go on/print on the Packaking slip, invoice, AND Shipping label.
Here's a snippet from the shipworks.php. I'm guessing I just have to add to this section but not sure what to add.
Thank you for any help.
$payment = $order->getPayment();
// CC info
if ($secure)
{
$cc_num = $payment->getCcNumber();
}
else
{
$cc_num = $payment->getCcLast4();
if (!empty($cc_num))
{
$cc_num = '************'.$payment->getCcLast4();
}
}
$cc_year = sprintf('%02u%s', $payment->getCcExpMonth(), substr($payment->getCcExpYear(), 2));
writeStartTag("Payment");
writeElement("Method", Mage::helper('payment')->getMethodInstance($payment->getMethod())->getTitle());
writeStartTag("CreditCard");
writeElement("Type", $payment->getCcType());
writeElement("Owner", $payment->getCcOwner());
writeElement("Number", $cc_num);
writeElement("Expires", $cc_year);
writeCloseTag("CreditCard");
writeCloseTag("Payment");
I was able to use the following to get my po number to show up in the notes. This is what I used. hope it helps.
// CC info
if ($secure)
{
$cc_num = $payment->getCcNumber();
}
else
{
$cc_num = $payment->getCcLast4();
if (!empty($cc_num))
{
$cc_num = '************'.$payment->getCcLast4();
}
}
$cc_year = sprintf('%02u%s', $payment->getCcExpMonth(), substr($payment->getCcExpYear(), 2));
writeStartTag("Payment");
writeElement("Method", Mage::helper('payment')->getMethodInstance($payment->getMethod())->getTitle());
writeStartTag("CreditCard");
writeElement("Type", $payment->getCcType());
writeElement("Owner", $payment->getCcOwner());
writeElement("Number", $cc_num);
writeElement("Expires", $cc_year);
writeCloseTag("CreditCard");
writeCloseTag("Payment");
writeStartTag("Notes");
writeFullElement("Note", $payment->getPoNumber(),array("public" =>"true"));
writeCloseTag("Notes");
WriteOrderItems($order->getAllItems());
WriteOrderTotals($order);
Shipworks is very picky about the XML tags that it receives. You can't just add something to the response because it'll throw errors in the SW software when it tries to sync with your Magento store. You can add it by using an existing element that isn't currently being used. In our case, we weren't using Gift Messages, which get added to the response as Notes, so I re-purposed the Notes element to contain something else.
Look at the WriteOrder function (around line 396) and find this section:
if ($order->getGiftMessageId())
{
$message = Mage::helper('giftmessage/message')->getGiftMessage($order->getGiftMessageId());
$messageString = "Gift message for ". $message['recipient']. ": ". $message['message'];
writeStartTag("Notes");
writeFullElement("Note", $messageString, array("public" => "true"));
writeCloseTag("Notes");
}
Comment out this section and add something like this:
if ($order->getPoNumber())
{
writeStartTag("Notes");
writeFullElement("Note", $order->getPoNumber(), array("public" => "true"));
writeCloseTag("Notes");
}
NOTE: I don't know if $order->getPoNumber() actually works...this is just a sample of what you'll need to do