[Update]: Added solutions using a WeakHashMap-Cache to get the cleaning of unused locks to be done by the garbage collector. They had been developed here: Iterating a WeakHashMap
If the payment has a reference to its order and equal orders are the same objects (order1 == order2 <=> order1 is the same as order2), you can use a synchronized block:
synchronized(payment.getOrder()) {
    try  {
       // ...
    }
}
Caution: You should ensure, that payment.getOrder() does not yield null or use dummy-Objects for that case.
Edit: Possible solution if order1 == order2 does not hold:
You could try holding unique locks for equal identifiers of your order:
static Map<Long, Object> lockCache = new ConcurrentHashMap<>();
and in the method
Object lock = new Object();
Object oldlock = lockCache.putIfAbsent(payment.getOrder().getUid(), lock);
if (oldlock != null) {
    lock = oldlock;
}
synchronized(lock) {
    // ...
}
Don't forget to remove the key when the work is done.
To use the garbage collection to remove your unused keys you could use a WeakHashMap structure:
private static Map<Long, Reference<Long>> lockCache = new WeakHashMap<>();
public static Object getLock(Longi)
{
    Long monitor = null;
    synchronized(lockCache) {
        Reference<Long> old = lockCache.get(i);
        if (old != null)
            monitor = old.get();
        // if no monitor exists yet
        if (monitor == null) {
            /* clone i for avoiding strong references 
               to the map's key besides the Object returend 
               by this method.
            */ 
            monitor = new Long(i);
            lockCache.remove(monitor); //just to be sure
            lockCache.put(monitor, new WeakReference<>(monitor));
        }
    }
    return monitor;
}
When you need something more complex like an reentant lock you may use a variation of the following solution:
private static Map<Long, Reference<ReentrantLock>> lockCache = new WeakHashMap<>();
private static Map<ReentrantLock, Long> keyCache = new WeakHashMap<>();
public static ReentrantLock getLock(Long i)
{
    ReentrantLock lock = null;
    synchronized(lockCache) {
        Reference<ReentrantLock> old = lockCache.get(i);
        if (old != null)
            lock = old.get();
        // if no lock exists or got cleared from keyCache already but not from lockCache yet
        if (lock == null || !keyCache.containsKey(lock)) {
            /* clone i for avoiding strong references 
               to the map's key besides the Object returend 
               by this method.
           */ 
            Long cacheKey = new Long(i); 
            lock = new ReentrantLock();
            lockCache.remove(cacheKey); // just to be sure
            lockCache.put(cacheKey, new WeakReference<>(lock));
            keyCache.put(lock, cacheKey);
        }                
    }
    return lock;
}